OpenSSL RSA_public_encrypt奇怪的行为

时间:2012-11-14 23:30:15

标签: ios openssl

我正在尝试使用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加密公钥?

我犯了错误?

2 个答案:

答案 0 :(得分:5)

这实际上是正确的,你没有犯错误。您的混淆源于RSA_PKCS1_OAEP_PADDING的{​​{1}}参数。

RSA加密过程实际上是:

  1. 采用明文(普通)和编码,生成encoded_plain。
  2. 加密encoded_plain。
  3. (正如您所料,解密过程要求您解密该值,然后解码该消息)。

    RSA_public_encrypt参数指定明文应如何编码(应使用OAEP编码)。

    简化说明是OAEP填充使用一些随机值进行填充,因此RSA_PKCS1_OAEP_PADDINGxxxxxxxABC以及yyyyyyyABC都是明文的有效encoded_plain值,而那些encoded_plain加密不同的价值。如果执行相应的解密(并通过将相同的zzzzzzzABC参数传递给RSA_PKCS1_OAEP_PADDING)进行解码,则仍应将“ABC”作为每个密文的输出,因为填充被剥离这三个。

    (如果你想要准确,OAEP编码方案更复杂,请参阅RFC 3447 section 7.1.1。但这些可能是你不关心的细节。)

答案 1 :(得分:0)

编码范围在rsa_encrypt函数末尾结束。你的返回指针将指向一个无效的内存区域,它可能不再包含你期望的内容,因为其他人(例如另一个线程)在上面写了。解释填充的答案是正确的。