我正在尝试使用OpenSSL在C中编写一个简单的加密例程,我发现了一些奇怪的东西。我不是C大师,也不是OpenSSL专业人士。所以我可能犯了一个错误。
功能如下
char *rsa_encrypt(char *data)
{
const char xponent_in_hex[] = "010001";
const char modulus_in_hex[] = "D0BA16F11907E7B0819705A15264AC29BEE9F1EC5F22642992
D3E27100B7F212864A624A12FFB6D531712B0B0225AAD0C2E313D077A7DB2A5A33483EEFF41A9D";
BIGNUM *xponent = NULL;
BIGNUM *modulus = NULL;
BN_hex2bn(&xponent, xponent_in_hex);
BN_hex2bn(&modulus, modulus_in_hex);
RSA *rsa = RSA_new();
rsa->e = xponent;
rsa->n = modulus;
rsa->iqmp = NULL;
rsa->d = NULL;
rsa->p = NULL;
rsa->q = NULL;
char encoded[512] = { 0 };
RSA_public_encrypt(
strlen(data),
(const unsigned char *)data,
(unsigned char *)encoded,
rsa,
RSA_PKCS1_OAEP_PADDING
);
RSA_free(rsa);
return (encoded);
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("%s\n", base64_encode(rsa_encrypt("ABC")));
printf("%s\n", base64_encode(rsa_encrypt("ABC")));
printf("%s\n", base64_encode(rsa_encrypt("ABC")));
}
我在相同的数据上多次调用该函数,每次调用它时都会生成不同的值。它显然是错误,因为指数和模数对于创建的 RSA结构是恒定的,输入数据在每个中是相同的呼叫。
为什么RSA_public_encrypt
表现那样?
如何根据指数和模数生成RSA加密公钥?
我犯了错误?
答案 0 :(得分:5)
这实际上是正确的,你没有犯错误。您的混淆源于RSA_PKCS1_OAEP_PADDING
的{{1}}参数。
RSA加密过程实际上是:
(正如您所料,解密过程要求您解密该值,然后解码该消息)。
RSA_public_encrypt
参数指定明文应如何编码(应使用OAEP编码)。
简化说明是OAEP填充使用一些随机值进行填充,因此RSA_PKCS1_OAEP_PADDING
和xxxxxxxABC
以及yyyyyyyABC
都是明文的有效encoded_plain值,而那些encoded_plain加密不同的价值。如果执行相应的解密(并通过将相同的zzzzzzzABC
参数传递给RSA_PKCS1_OAEP_PADDING
)进行解码,则仍应将“ABC”作为每个密文的输出,因为填充被剥离这三个。
(如果你想要准确,OAEP编码方案更复杂,请参阅RFC 3447 section 7.1.1。但这些可能是你不关心的细节。)
答案 1 :(得分:0)
编码范围在rsa_encrypt函数末尾结束。你的返回指针将指向一个无效的内存区域,它可能不再包含你期望的内容,因为其他人(例如另一个线程)在上面写了。解释填充的答案是正确的。