endianness - 为了在 libcrypto 中与 CryptoAPI 兼容的签名,更改 PEM 编码的私钥/公钥对的字节序
问题描述
我正在编写一个程序,它能够签署和验证最初为 CryptoAPI(旧的 Windows 加密库)制作的签名。目标是能够从 linux 签名/验证。
但是,由于 CryptoAPI 和 libcrypto 具有不同的字节顺序,我似乎碰壁了。
我已经尝试颠倒要验证的签名的顺序(整个 128 字节的 RSA 加密块,带有填充和所有)。这似乎还不够,我正在努力寻找一个合适的直截了当的食谱来轻松地做到这一点。
我从另一个 stackoverflow 帖子中发现,您需要反转实际密钥的字节序。因此,我想知道是否有任何简单的方法可以做到这一点,我最好不必自己弄乱数据。
我将坚持验证,因为我假设相同的工作流程可以应用于私钥 PEM。情况是这样的:
我将公钥作为 PEM,使用命令转换
openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in pkey_mspublic.bin -outform PEM -out pubkey.pem
以下是我如何将 PEM 加载到 libcrypto 并验证签名:
BIO* certBio = BIO_new_mem_buf((void*)pubkey, -1);
RSA* rsa = NULL;
rsa = PEM_read_bio_RSA_PUBKEY(certBio, &rsa,NULL, NULL);
for (int i=0; i <signatureLength; i++)
{
char tmp = expectedHashPtr[i];
expectedHashPtr[i] = expectedHashPtr[signatureLength - 1 - i];
expectedHashPtr[signatureLength - 1 - i] = tmp;
}
EVP_PKEY* pubKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pubKey, rsa);
std::cout << "pubkey size: " << EVP_PKEY_size(pubKey) << std::endl;
EVP_MD_CTX* mdctx = EVP_MD_CTX_create();
if(!(mdctx = EVP_MD_CTX_create())) std::cout << "ctx create fail" << std::endl;
if(1 != EVP_VerifyInit(mdctx, EVP_md5())) std::cout << "digest init fail" << std::endl;
if(1 != EVP_VerifyUpdate(mdctx, data, 512)) std::cout << "digest fail" << std::endl;
std::cout << "finishing verify" << std::endl;
if(1 == EVP_VerifyFinal(mdctx, (unsigned char*)expectedHashPtr, signatureLength, pubKey))
{
/* Success */
std::cout << "Success" << std::endl;
return true;
}
else
{
ERR_print_errors_fp(stderr);
std::cout << "Fail" << std::endl;
return false;
}
当我运行上面的代码时,我得到了填充错误,我认为这是因为我的键是错误的字节序,因此是错误的:
140278264301376:error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:67:
140278264301376:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:582:
所以,我的问题是,是否有一种快速简便的方法来处理 PEM 格式的公钥和私钥的字节序转换?我不想手动执行此操作,因为它必须按比例缩放。
解决方案
推荐阅读
- python - 将字节数组转换为int python错误结果
- python - 将 anaconda 升级到最新版本时遇到很多冲突
- javascript - 我如何重写功能代码javascript
- azure - 所需的网络安全组更新 - 端口 5986
- python - 忽略第一次出现的字母正则表达式
- next.js - Browserslist:caniuse-lite 已过时。请运行:npx browserslist@latest --update-db NextJS
- node.js - 在节点 js 中获取 POST 请求
- google-apps-script - 通过 Gmail 网站发送草稿时,如何在 GmailApp.createDraft() 创建的 Gmail 草稿中保留回复设置?
- arduino - 验证错误问题,类型 0x0000 的第一个不匹配
- python - 在 10 x 10 矩阵中,为什么这个数组表示法不起作用?