C: OpenSSL RSA_private_decrypt() fails with "error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error”
C: OpenSSL RSA_private_decrypt() fails with "error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error”
我是密码学的新手,所以我决定创建一个简单的程序来打开一个文件加密数据,将其放入 etest.txt,然后打开这个文件解密并放入 etest.txt.我知道这听起来很奇怪,但它是出于教育目的。所以这是我的代码。我已经阅读了很多关于此问题的主题,但其中 none 对我有用。
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
int main(void) {
size_t pri_len; // Length of private key
size_t pub_len; // Length of public key
char *pri_key; // Private key
char *pub_key; // Public key
char *msg = malloc(256); // Message to encrypt
char *encrypt = NULL; // Encrypted message
char *decrypt = NULL; // Decrypted message
char *err; // Buffer for any error messages
size_t red;
RSA *keypair = RSA_generate_key(2048, 3, NULL, NULL);
FILE *in = fopen("test.txt", "r");
FILE *out = fopen("etest.txt", "w");
if(in == NULL)
{
printf("in Error is %d (%s).\n", errno, strerror(errno));
}
if(out == NULL)
{
printf("out Error is %d (%s).\n", errno, strerror(errno));
}
encrypt = malloc(RSA_size(keypair));
for(;;)
{
red = fread(msg, 1, RSA_size(keypair)-42, in);
if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error encrypting message: %s\n", err);
}
if(fwrite(encrypt, 1, strlen(encrypt), out) == 1)
{
printf("fwrite Error is %d (%s).\n", errno, strerror(errno));
}
if(feof(in))
{
break;
}
}
fclose(in);
fclose(out);
in = fopen("etest.txt", "r");
out = fopen("dtest.txt", "w");
if(in == NULL)
{
printf("in Error is %d (%s).\n", errno, strerror(errno));
}
if(out == NULL)
{
printf("out Error is %d (%s).\n", errno, strerror(errno));
}
decrypt = malloc(RSA_size(keypair));
for(;;)
{
red = fread(msg, 1, 256, in);
if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error decrypting message: %s\n", err);
}
fwrite(decrypt, 1, strlen(decrypt), out);
if(feof(in))
{
break;
}
}
fclose(in);
fclose(out);
RSA_free(keypair);
return 0;
}
当我 运行 编码时,它返回错误提示:Error decrypting message: error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error
对不起,如果我的问题听起来很愚蠢。希望你能帮忙。谢谢。
这里有一些错误。首先当你阅读和加密时:
red = fread(msg, 1, RSA_size(keypair)-42, in);
if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
调用 fread
不一定会读取请求的字节数,可能会 return 0。所以当你到达文件末尾时,你会加密更多字节比你需要的。因此,传入 red
作为要加密的字节数。此外,首先检查 red
是否为 0,如果是,则 break
退出循环:
red = fread(msg, 1, RSA_size(keypair)-42, in);
if (red == 0) break;
if(((red=RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING))) == -1) {
请注意,我们正在保存 RSA_public_encrypt
的 return 值。这在您将加密数据写入磁盘的地方发挥作用:
if(fwrite(encrypt, 1, strlen(encrypt), out) == 1)
encrypt
是字符数组,不是字符串。这意味着它不是 NULL 终止的,并且它可能包含 NULL 字节。所以你不能使用strlen
。相反,捕获 RSA_public_encrypt
的 return 值并将其作为要写入的大小传递:
if(fwrite(encrypt, 1, red, out) == 1)
因为我们正在检查 fread
的 return 值以跳出循环,所以不需要这样做:
if(feof(in))
{
break;
}
有关使用 feof
的危险,请参阅 this post。
然后当你读回加密数据时是这样的:
red = fread(msg, 1, 256, in);
if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
RSA_private_decrypt
需要一个长度为 RSA_size(keypair)
的加密块。所以从磁盘中读取那么多字节并将那么多字节传递给函数。另外,如果没有得到预期的数量,请检查 fread
和 break
的 return 值,并捕获 RSA_private_decrypt
的 return 值:
red = fread(msg, 1, RSA_size(keypair), in);
if (red < RSA_size(keypair)) break;
if((red=RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
稍后将解密数据写入磁盘时:
fwrite(decrypt, 1, strlen(decrypt), out);
虽然被解密的可能是一个字符串(如果您的输入文件是纯文本),returned 数据不是 NULL 终止的,所以显式地写很多字节而不是使用 strlen
:
fwrite(decrypt, 1, red, out);
最后,与加密循环一样,解密循环中不需要:
if(feof(in))
{
break;
}
应用这些修复后,您应该会得到预期的结果。
我是密码学的新手,所以我决定创建一个简单的程序来打开一个文件加密数据,将其放入 etest.txt,然后打开这个文件解密并放入 etest.txt.我知道这听起来很奇怪,但它是出于教育目的。所以这是我的代码。我已经阅读了很多关于此问题的主题,但其中 none 对我有用。
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
int main(void) {
size_t pri_len; // Length of private key
size_t pub_len; // Length of public key
char *pri_key; // Private key
char *pub_key; // Public key
char *msg = malloc(256); // Message to encrypt
char *encrypt = NULL; // Encrypted message
char *decrypt = NULL; // Decrypted message
char *err; // Buffer for any error messages
size_t red;
RSA *keypair = RSA_generate_key(2048, 3, NULL, NULL);
FILE *in = fopen("test.txt", "r");
FILE *out = fopen("etest.txt", "w");
if(in == NULL)
{
printf("in Error is %d (%s).\n", errno, strerror(errno));
}
if(out == NULL)
{
printf("out Error is %d (%s).\n", errno, strerror(errno));
}
encrypt = malloc(RSA_size(keypair));
for(;;)
{
red = fread(msg, 1, RSA_size(keypair)-42, in);
if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error encrypting message: %s\n", err);
}
if(fwrite(encrypt, 1, strlen(encrypt), out) == 1)
{
printf("fwrite Error is %d (%s).\n", errno, strerror(errno));
}
if(feof(in))
{
break;
}
}
fclose(in);
fclose(out);
in = fopen("etest.txt", "r");
out = fopen("dtest.txt", "w");
if(in == NULL)
{
printf("in Error is %d (%s).\n", errno, strerror(errno));
}
if(out == NULL)
{
printf("out Error is %d (%s).\n", errno, strerror(errno));
}
decrypt = malloc(RSA_size(keypair));
for(;;)
{
red = fread(msg, 1, 256, in);
if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error decrypting message: %s\n", err);
}
fwrite(decrypt, 1, strlen(decrypt), out);
if(feof(in))
{
break;
}
}
fclose(in);
fclose(out);
RSA_free(keypair);
return 0;
}
当我 运行 编码时,它返回错误提示:Error decrypting message: error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error
对不起,如果我的问题听起来很愚蠢。希望你能帮忙。谢谢。
这里有一些错误。首先当你阅读和加密时:
red = fread(msg, 1, RSA_size(keypair)-42, in);
if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
调用 fread
不一定会读取请求的字节数,可能会 return 0。所以当你到达文件末尾时,你会加密更多字节比你需要的。因此,传入 red
作为要加密的字节数。此外,首先检查 red
是否为 0,如果是,则 break
退出循环:
red = fread(msg, 1, RSA_size(keypair)-42, in);
if (red == 0) break;
if(((red=RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING))) == -1) {
请注意,我们正在保存 RSA_public_encrypt
的 return 值。这在您将加密数据写入磁盘的地方发挥作用:
if(fwrite(encrypt, 1, strlen(encrypt), out) == 1)
encrypt
是字符数组,不是字符串。这意味着它不是 NULL 终止的,并且它可能包含 NULL 字节。所以你不能使用strlen
。相反,捕获 RSA_public_encrypt
的 return 值并将其作为要写入的大小传递:
if(fwrite(encrypt, 1, red, out) == 1)
因为我们正在检查 fread
的 return 值以跳出循环,所以不需要这样做:
if(feof(in))
{
break;
}
有关使用 feof
的危险,请参阅 this post。
然后当你读回加密数据时是这样的:
red = fread(msg, 1, 256, in);
if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
RSA_private_decrypt
需要一个长度为 RSA_size(keypair)
的加密块。所以从磁盘中读取那么多字节并将那么多字节传递给函数。另外,如果没有得到预期的数量,请检查 fread
和 break
的 return 值,并捕获 RSA_private_decrypt
的 return 值:
red = fread(msg, 1, RSA_size(keypair), in);
if (red < RSA_size(keypair)) break;
if((red=RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
稍后将解密数据写入磁盘时:
fwrite(decrypt, 1, strlen(decrypt), out);
虽然被解密的可能是一个字符串(如果您的输入文件是纯文本),returned 数据不是 NULL 终止的,所以显式地写很多字节而不是使用 strlen
:
fwrite(decrypt, 1, red, out);
最后,与加密循环一样,解密循环中不需要:
if(feof(in))
{
break;
}
应用这些修复后,您应该会得到预期的结果。