我一直在使用Crypto++开发数字签名者和验证器。我分析了以下问题:我的签名者和验证器很好地处理了我通过编程方式从这个维基生成的公钥和私钥(生成一个RSA密钥并保存它)。但是,当我使用另一个测试密钥对进行测试时,当我尝试加载用于签名的密钥时,会出现以下错误:“误码解码错误”。我一直在网上搜索,但解决不了这个问题。以下是我的课程:
class DSUtility
{
protected:
DSUtility() = default;
template<typename KeyType, typename KeySourceType>
KeyType PrepareKey_(const std::string& key_source);
};
template<typename KeyType, typename KeySourceType>
KeyType DSUtility::PrepareKey_(const std::string& key_source)
{
CryptoPP::ByteQueue key_bytes;
KeySourceType(key_source.c_str(), true, new CryptoPP::Base64Decoder).TransferTo(key_bytes);
key_bytes.MessageEnd();
KeyType key;
key.Load(key_bytes); // FAILS WHEN TRYING TO SIGN WITH ANOTHER PRIVATE KEY
return key;
}
class Signer : private DSUtility
{
public:
Signer(const std::string& private_key);
std::string Sign(const std::string& data);
private:
typedef CryptoPP::RSA::PrivateKey PrivateKey;
CryptoPP::RSASS<CryptoPP::PKCS1v15, CryptoPP::SHA256>::Signer signer_;
};
Signer::Signer(const std::string& private_key) :
signer_(PrepareKey_<PrivateKey, CryptoPP::StringSource>(private_key))
{
}
std::string Signer::Sign(const std::string& data)
{
CryptoPP::SecByteBlock signature(signer_.SignatureLength());
signer_.SignMessage(CryptoPP::AutoSeededRandomPool(), (byte const*)data.c_str(), data.size(), signature);
return std::string(signature.begin(), signature.end());
}我的一把钥匙(能用)看上去如下:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAILkZnFV77ckeZkepDk1fvsE
qli05im29PTZq0ayWZsSgis+tpzP2KpSigWimAfkOCF36Y1Zb9E8VcxBaRbEEH0ObQTQdOl0
z1Cf0mViD2dQgH+8ZucU2gKy0YDpjIJ6wZM55azNZBg1s5J9PuDyM+nMRh5RiJqEpaXSXzgV...另一张看起来如下:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDGwB5n/xMsDoqo+bGaws15FYGGjsJxCM2deHJZqV2QKfvkmStf
8HntPqaJ+mc9UA6ghN1uGndChg1PuHSNVaRU2x8fem/mFUhfOJaZcYich8JAy0nm
sJUOwoRqLfKjLWmqy0QZHXDDVw+sD5uq/oOvfFFjuYIcsskHQmGTfkdJrQIDAQAB...发布于 2015-11-10 12:16:10
但是,当我使用另一个测试密钥对进行测试时,当我尝试加载用于签名的密钥时,会出现以下错误:“误码解码错误”。
很难说到底出了什么问题..。您应该提供真实的测试密钥。用“.”来破解假货是不值得的。“因为我们知道它会失败。
我只是猜测,但它可能是一个原始密钥(即只有公钥或私钥,没有标识符),而不是密钥信息(即内部公钥或私钥的外部序列和标识符)。后者(密钥信息)有时被称为公钥时的subjectPublicKeyIdnfo。
您可能想看看键和格式上的Crypto++ wiki。你引用的指南有点旧,是为了历史目的而提供的。这是3秒钟的巡回演出:
raw key,调用时,BERDecodekey info,调用时,Loadraw key,调用DEREecode时key info,调用Save时CryptoPP::Base64Decoder).TransferTo(key_bytes);KeyType,typename KeySourceType> KeyType DSUtility::PrepareKey_(const std::string& key_source) { CryptoPP::ByteQueue key_bytes;KeySourceType(key_source.c_str(),true,新的KeySourceType> key_bytes.MessageEnd();KeyType key;key.Load(key_bytes);//在尝试用另一个私钥返回键签名时失败);
这可能可以简化一点:
template<typename KeyType, typename KeySourceType> KeyType
DSUtility::PrepareKey_(const std::string& key_source)
{
ArraySource as((const byte*)key_source.data(), key_source.size(),
true, new Base64Decoder());
key.Load(as);
return key;
}如果它是一个raw key,,您可以尝试:
key.BERDecode(as);“.另一个看起来如下:
-----BEGIN RSA PRIVATE KEY-----__.”
有关PEM编码的密钥,请参见PEM包上的Crypto++ wiki。
这里引用了一个堆栈溢出问题,但它只是引用了Crypto++ wiki页面(除了其他答案):在Crypto++中加载PEM编码的私钥。
尝试用另一个私钥签名时失败
此外,“尝试签署另一个私钥时失败”与“尝试加载时失败”不同。我试着把注意力集中在你问的问题上,所以这可能不是你所期望的答案。
在您花一些时间在堆栈溢出问题上之后,您可能会厌倦那些回答他们希望是而不是的问题的人--实际上所问的问题。我很快就厌倦了,所以我试着在回答时保持专注(这就是为什么我会引用我回答的所有内容,即使这是我的评论)。
https://stackoverflow.com/questions/33603141
复制相似问题