上面提到的 PKCS#1 文档更具数学性,没有给出编码示例,CMS 的答案是针对 ASN.1/SMIME 数据的,与所提出的问题并不真正相关,即如何替换RSA_public_encrypt()
处理简单二进制的问题/文本数据。我花了一整天的时间反复试验和在线搜索以找到答案,并最终通过查看“openssl pkeyutl”的源代码得到了答案(即使用 OpenSSL 的 EVP API)——一旦我发现它并不难。
在我的情况下,我希望RSA_private_decrypt()
使用私钥替换解密,这就是如何做到这一点 - 基于此将 RSA_public_encrypt() 替换放在一起应该很容易:
EVP_PKEY *privKey = NULL;
BIO *bioPrivKey;
int outLen = 0, ret;
if ((bioPrivKey = BIO_new(BIO_s_mem())))
{
// Read the private key from the RSA context into the memory BIO,
// then convert it to an EVP_PKEY:
if ((ret = PEM_write_bio_RSAPrivateKey(bioPrivKey, rsaCtxt, NULL, NULL, 0, NULL, NULL)) &&
(privKey = PEM_read_bio_PrivateKey(bioPrivKey, NULL, NULL, NULL)))
{
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(privKey, NULL);
EVP_PKEY_free(privKey);
if (ctx)
{
if (EVP_PKEY_decrypt_init(ctx) > 0)
{
EVP_PKEY_CTX_ctrl_str(ctx, "rsa_padding_mode", "oaep");
EVP_PKEY_CTX_ctrl_str(ctx, "rsa_oaep_md", "sha256");
EVP_PKEY_CTX_ctrl_str(ctx, "rsa_mgf1_md", "sha256");
outLen = dataOutMax;
ret = EVP_PKEY_decrypt(ctx, dataOut, &outLen, dataIn, inDataLen);
if (ret > 0 && outLen > 0 && outLen <= dataOutMax)
{
// Success :-)
}
}
EVP_PKEY_CTX_free(ctx);
}
}
BIO_free_all(bioPrivKey);
}
您可以使用 ERR_get_error() 为失败案例添加错误处理。