You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Crypto++中从硬编码字符串加载RSA私钥?

问题:硬编码DER格式RSA私钥到Crypto++程序时触发BERDecodeErr异常

背景

通过以下步骤生成并转换RSA私钥:

  1. 用OpenSSL生成PEM格式私钥:
    openssl genrsa -out privatKey.pem 2048
    
  2. 转换为PKCS#8 DER格式以适配Crypto++加载:
    openssl pkcs8 -in privatKey.pem -out privatKey.der -topk8 -nocrypt -outform der
    

从文件加载该DER密钥的代码可正常运行:

ByteQueue queue;
FileSource file("privatKey.der", true);
file.TransferTo(queue);
queue.MessageEnd();

RSA::PrivateKey rsaPrivate;
rsaPrivate.Load(queue);

问题场景

尝试将密钥硬编码到代码中:

  1. 用xxd -p privatKey.der导出十六进制字符串,赋值给std::string privKeyStr
  2. 用StringSource加载该字符串时,抛出CryptoPP::BERDecodeErr异常:
std::string privKeyStr = "308204bd020100300d06092a864886f70d0101010500048204a7308204a3"
"0201000282010100ba077fcaf8908c0b9bfef58f4493c93affb6ca7b2947"
// 省略剩余十六进制内容
"64c1af4ce4857b1cba7b21d7d59a7e5ab9";

ByteQueue queue;
StringSource str(privKeyStr, true);
str.TransferTo(queue);
queue.MessageEnd();

RSA::PrivateKey rsaPrivate;
rsaPrivate.Load(queue); // 此处抛出BERDecodeErr

原因分析

xxd -p输出的是ASCII格式的十六进制字符序列(比如字符'3'、'0'对应的ASCII值是0x33、0x30),而RSA::PrivateKey.Load()需要的是DER格式的原始二进制字节。直接传递ASCII字符串会导致解码时无法识别BER格式的结构,从而抛出异常。

解决方案

方案1:用Crypto++ HexDecoder解码十六进制字符串

通过HexDecoder将ASCII十六进制字符串转换为二进制字节流,再传入ByteQueue:

#include <cryptopp/hex.h>
#include <cryptopp/rsa.h>
#include <cryptopp/queue.h>
#include <cryptopp/strings.h>

std::string privKeyStr = "308204bd020100300d06092a864886f70d0101010500048204a7308204a3"
"0201000282010100ba077fcaf8908c0b9bfef58f4493c93affb6ca7b2947"
// 省略剩余十六进制内容
"64c1af4ce4857b1cba7b21d7d59a7e5ab9";

ByteQueue queue;
// 解码十六进制字符串到二进制队列
StringSource str(privKeyStr, true, new HexDecoder(new Redirector(queue)));
queue.MessageEnd();

RSA::PrivateKey rsaPrivate;
rsaPrivate.Load(queue); // 正常加载

方案2:直接生成C++二进制字节数组(推荐)

使用xxd -i命令直接生成可嵌入代码的二进制字节数组,避免运行时解码开销:

xxd -i privatKey.der > privkey.h

生成的privkey.h内容示例:

unsigned char privatKey_der[] = {
  0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
  // 剩余字节由xxd自动生成
};
unsigned int privatKey_der_len = 1213; // 实际长度与密钥匹配

加载该字节数组的代码:

#include "privkey.h"
#include <cryptopp/rsa.h>
#include <cryptopp/queue.h>
#include <cryptopp/arrays.h>

ByteQueue queue;
ArraySource arr(privatKey_der, privatKey_der_len, true, new Redirector(queue));
queue.MessageEnd();

RSA::PrivateKey rsaPrivate;
rsaPrivate.Load(queue); // 正常加载

内容的提问来源于stack exchange,提问作者ibse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:55:53