rsa_private_encrypt()和rsa_public_decrypt()意外无效的填充错误
我试图用私钥加密并用公共密钥进行加密,并用rsa_pkcs1_padding
作为填充。加密效果很好,但是当我进行解密时,我遇到了一个无效的填充错误:
processed 9 of 256 bytes, RSA_public_decrypt() error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding
有人知道这里有什么问题吗?附加完整源代码:
void encrypt_stdout(const char *from_file, int to_base64, int padding)
{
unsigned char *input = NULL, *output = NULL, *output2 = NULL;
int output_fd = -1, input_len = 0, output_len = 0, output2_len = 0;
if (readfile(from_file, &input, &input_len) != 0)
{
goto end;
}
output = malloc(RSA_size(rsa));
if (output == NULL)
{
fprintf(stderr, "malloc() on output: %s\n", strerror(errno));
goto end;
}
output_len = RSA_private_encrypt(input_len, input, output, rsa, padding);
if (output_len == -1)
{
fprintf(stderr, "RSA_private_encrypt() %s\n",ERR_error_string(ERR_get_error(), errbuf));
}
else
{
if (to_base64)
{
}
write(1, output, output_len);
}
end:
if (input != NULL)
{
free(input);
}
if (output != NULL)
{
free(output);
}
}
void decrypt_stdout(const char *from_file, int is_base64, int skip_bytes, int padding)
{
unsigned char *input = NULL, *output = NULL, *output2 = NULL;
int output_fd = -1, input_len = 0, output_len = 0, output2_len = 0, total_read = skip_bytes;
if (readfile(from_file, &input, &input_len) != 0)
{
goto end;
}
if (is_base64)
{
if (base64_decode(input, input_len, &output2, &output2_len) != 0)
{
if (output2 != NULL)
free(output2);
goto end;
}
free(input);
input = output2;
input_len = output2_len;
}
output = malloc(RSA_size(rsa));
if (output == NULL)
{
fprintf(stderr, "malloc() on output: %s\n", strerror(errno));
goto end;
}
while (total_read < input_len)
{
memset(output, 0, RSA_size(rsa));
output_len = RSA_public_decrypt(RSA_size(rsa), input + total_read, output, rsa, padding);
if (output_len == -1)
{
fprintf(stderr, "\nprocessed %d of %d bytes, RSA_public_decrypt() %s\n", total_read, input_len, ERR_error_string(ERR_get_error(), errbuf));
break;
}
else
{
write(STDOUT_FILENO, output, output_len);
}
total_read += output_len;
}
end:
if (input != NULL)
{
free(input);
}
if (output != NULL)
{
free(output);
}
}
I'm trying to encrypt with private key and decrypt with public key, with RSA_PKCS1_PADDING
as padding. The encryption works fine, but when I do the decryption I got an invalid padding error:
processed 9 of 256 bytes, RSA_public_decrypt() error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding
Anyone know what's wrong here? Attached full source code:
void encrypt_stdout(const char *from_file, int to_base64, int padding)
{
unsigned char *input = NULL, *output = NULL, *output2 = NULL;
int output_fd = -1, input_len = 0, output_len = 0, output2_len = 0;
if (readfile(from_file, &input, &input_len) != 0)
{
goto end;
}
output = malloc(RSA_size(rsa));
if (output == NULL)
{
fprintf(stderr, "malloc() on output: %s\n", strerror(errno));
goto end;
}
output_len = RSA_private_encrypt(input_len, input, output, rsa, padding);
if (output_len == -1)
{
fprintf(stderr, "RSA_private_encrypt() %s\n",ERR_error_string(ERR_get_error(), errbuf));
}
else
{
if (to_base64)
{
}
write(1, output, output_len);
}
end:
if (input != NULL)
{
free(input);
}
if (output != NULL)
{
free(output);
}
}
void decrypt_stdout(const char *from_file, int is_base64, int skip_bytes, int padding)
{
unsigned char *input = NULL, *output = NULL, *output2 = NULL;
int output_fd = -1, input_len = 0, output_len = 0, output2_len = 0, total_read = skip_bytes;
if (readfile(from_file, &input, &input_len) != 0)
{
goto end;
}
if (is_base64)
{
if (base64_decode(input, input_len, &output2, &output2_len) != 0)
{
if (output2 != NULL)
free(output2);
goto end;
}
free(input);
input = output2;
input_len = output2_len;
}
output = malloc(RSA_size(rsa));
if (output == NULL)
{
fprintf(stderr, "malloc() on output: %s\n", strerror(errno));
goto end;
}
while (total_read < input_len)
{
memset(output, 0, RSA_size(rsa));
output_len = RSA_public_decrypt(RSA_size(rsa), input + total_read, output, rsa, padding);
if (output_len == -1)
{
fprintf(stderr, "\nprocessed %d of %d bytes, RSA_public_decrypt() %s\n", total_read, input_len, ERR_error_string(ERR_get_error(), errbuf));
break;
}
else
{
write(STDOUT_FILENO, output, output_len);
}
total_read += output_len;
}
end:
if (input != NULL)
{
free(input);
}
if (output != NULL)
{
free(output);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是由
引起的
循环decrypt_stdout()
。对我来说,这个循环的感觉尚不清楚。而不是循环,它应该与
encrypt_stdout()
相当类似,因此,解密在我的计算机上起作用。
但是,如果使用循环,则第一个解密会成功并返回明文,而随后的解密失败并返回A -1,从而导致错误消息的输出。
关于代码中使用的逻辑的一些注释:
既然您谈论加密和解密:
rsa_private_encrypt()
和rsa_public_decrypt()
并不是真正用于加密和解密,而是用于低级签名和验证。通常,当使用
rsa_private_encrypt()签名时,传递的不是数据本身,而是使用摘要ID前缀的数据(更准确地说,更准确地说,是 digestinfo的der编码) 值)。在已发布的代码中,既没有哈希也没有预发摘要ID。当然,加载的文件可能已经包含Digest ID和Hash的串联,但是如果没有示例数据,就无法说。如果不是这种情况,则生成的签名不符合PKCS#1 V1.5填充。
如果不进行散列,则必须注意满足长度标准,即要签名的数据必须小于关键大小,减去填充所需的最小空间(PKCS#1 v1.5 padding或
flag_padding
= 1)。为了完整性:PKCS#1 V1.5填充是确定性的(在签名的背景下)。填充数据看起来像这样:0x00 || 0x01 || PS || 0x00 || t,ps由如此多的0xff值组成,以至于大小等于密钥大小。 t是数据,如果符合规范,则是摘要ID和哈希数据的串联,s。 rfc8017 。
The problem is caused by the
while
loop indecrypt_stdout()
.To me the sense of this loop is not clear. Instead of the loop it should be quite analogous to
encrypt_stdout()
:With this, decryption works on my machine.
However, if the loop is used, the first decryption succeeds and returns the plaintext, while the subsequent decryption fails and returns a -1, resulting in the output of the error message.
A few notes on the logic used in the code:
Since you talk about encryption and decryption:
RSA_private_encrypt()
andRSA_public_decrypt()
are not really meant for encryption and decryption, but for low level signing and verification.Typically, when signing with
RSA_private_encrypt()
, it is not the data itself that is passed, but a hash of the data prefixed with a digest ID (more precisely, the DER encoding of the DigestInfo value). In the posted code, there is neither hashing nor prepending a digest ID. Of course, the loaded file might already contain the concatenation of digest ID and hash, but that cannot be said without sample data. If this is not the case, the generated signature is not compliant with PKCS#1 v1.5 padding.If no hashing takes place, care must be taken that the length criterion is met, i.e. the data to be signed must be smaller than the key size minus the minimum space required by the padding (11 bytes for PKCS#1 v1.5 padding or
flag_padding
= 1).For completeness: PKCS#1 v1.5 padding is determinstic (in the context of signing). The padded data looks like this: 0x00 || 0x01 || PS || 0x00 || T, where PS consists of so many 0xff values that the size is equal to the key size. T is the data or, if compliant with the specification, the concatenation of digest ID and hashed data, s. RFC8017.