使用不同算法的 PKCS1v15 填充进行加密 ++ 签名

Crypto++ Signing with PKCS1v15 padding with different algorithms

本文关键字:加密 签名 填充 PKCS1v15 算法      更新时间:2023-10-16

我想知道Crypto++是否只使用SHA(RSASSA_PKCS1v15_SHA_Signer(对文件进行签名?

我一直在使用pyCryptodome进行签名和验证,但我想创建一个C++应用程序来做同样的事情。在 Python 中,我可以使用任何受支持的哈希(SHA3/BLAKE2B 等(算法对文件进行签名。至少我想支持在C++中使用 SHA256 进行签名。

std::string Hasher::sign(const std::string& message)
{
RSASSA_PKCS1v15_SHA_Signer signer(m_privateKey);
size_t length = signer.MaxSignatureLength();
SecByteBlock signature(length);
length = signer.SignMessage(rng, (CryptoPP::byte*)message.c_str(), message.size(), signature);
signature.resize(length);
//Want the signature as a hex
return toHex(signature, signature.size());
}

但是,我希望能够做一些类似于我在 Python 中做的事情:

def(message, key, passphrase, hashType):
rsakey = RSA.importKey(key,passphrase)
signer = PKCS1_v1_5.new(rsakey)
# Get the hash class based os user given hashType ex ("SHA256" returns "SHA256.New()")
digest = getHash(hashType)
digest.update(message.encode("ascii"))
return signer.sign(digest).hex()

如果我选择相同的私钥,并使用hashType"SHA",我会得到与C++代码相同的签名结果。

所以我找到了答案。所以部分遵循此处的教程 从RSASS<PSS, SHA256>::Signer signer(privateKey);您可以添加 PKCS1v15 填充,如下所示RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);所以最终的代码看起来像这样:

std::string Hasher::sign(const std::string& message)
{
CryptoPP::RSASS<CryptoPP::PKCS1v15, CryptoPP::SHA256>::Signer signer(m_privateKey);
size_t length = signer.MaxSignatureLength();
SecByteBlock signature(length);
length = signer.SignMessage(rng, (CryptoPP::byte*)message.c_str(), message.size(), signature);
signature.resize(length);
//Want the signature as a hex
return toHex(signature, signature.size());
}

如此超级相似,我仍然不知道为什么RSASSA_PKCS1v15_SHA_Signer类仍然存在。为了抛出一些额外的我最终目标,因为除了邮件列表中的一个随机 13 岁的问题外,我什么也找不到: 如何使用 Crypto++ 对文件进行签名和验证(就像在 pyCrypto 中对文件进行签名一样(

签名文件:

std::string Hasher::sign()
{
CryptoPP::RSASS<CryptoPP::PKCS1v15, CryptoPP::SHA256>::Signer signer(m_privateKey);
size_t length = signer.MaxSignatureLength();
SecByteBlock signature(length);
// Get bytes of the file
const auto& data = getFileBytes();
//AFAIK you need to create a signer PK_MessageAccumulator object to acheive this
CryptoPP::PK_MessageAccumulator* pSigMsgAcc = signer.NewSignatureAccumulator(rng);
//Update it with your data, toBinary_const is just a short for (const CryptoPP::byte*)data.data()
pSigMsgAcc->Update(toBinary_const(data), data.size());
length = signer.Sign(rng, pSigMsgAcc, signature);
signature.resize(length);
//I return it as hex as people can actually read the signature and verify it themself
return toHex(signature, signature.size());
}

验证文件

bool Hasher::verify(const std::string& signature, const std::string& type)
{
CryptoPP::RSASS<CryptoPP::PKCS1v15, CryptoPP::SHA256>::Verifier verifier(m_publicKey);
const auto& data                             = getFileBytes();
//Create a verifyer PK_MessageAccumulator object
CryptoPP::PK_MessageAccumulator* pVrfyMsgAcc = verifier.NewVerificationAccumulator();
pVrfyMsgAcc->Update(toBinary_const(data), data.size());
//Here comes the down side of using hex as signatrue, I convert it to a binary string
auto toVerify = toBinaryString(signature);
//Then I have to convert the binary string to binary
// (It does not like me to convert the hex directly to binary)
verifier.InputSignature(*pVrfyMsgAcc, toBinary_const(toVerify), toVerify.size());
return verifier.Verify(pVrfyMsgAcc);
}