在Java中,我使用填充来使用Bouncy Castle
加密数据:
Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
Base64编码结果为:
AAAAAAAAAAAAAAAAA.....H6hBDxOrCI0K8fd13vOYtsKdo4SI3VZTa3...
Ant每次都不会改变。
在C ++中,我使用OpenSSL
库来加密数据:
RSA_public_encrypt(rsa_len, (unsigned char *)str, (unsigned char*)p_en, p_rsa, RSA_NO_PADDING);
Base64编码结果为:
bxeeBPfFRJsLOzJLMS/qGKtDe1zPw8H491QsE+uuRRay6/ep69fqv386j8...
每次运行代码时都会更改。
我读了Wiki并知道RSA encryption is a deterministic encryption algorithm。
所以java的结果是合理的,我的问题是:
更新
我发现我的java代码是正确的。 并且When calling RSA_private_encrypt with RSA_NO_PADDING, the input must have the same size as the RSA key modulus.。在我将输入填充为256字节后,openssl可以解密java加密结果。
所以,问题变为:
openssl做了什么来填充输入以达到所需的长度?
更新
最后,我没有太多时间在openssl中研究OAEP。由于历史问题,服务器使用这种不安全的方式。所以我用字节0填充我的输入。就像:
This is input //<-----following many ASCII 0 char to reach 256 bytes length
但这会导致输出相同。任何其他代码都应该在服务器和客户端中阻止这种情况。
答案 0 :(得分:2)
每次运行代码时它都会改变。
是。那是由于Optimal Asymmetric Encryption Padding (OAEP)。
如果您发送两次相同的消息,例如黎明时的攻击,那么观察该消息的对手在看到该消息时将无法学到任何东西(或做出有根据的猜测)消息再次。该属性称为语义安全性或Ciphertext Indistinguishability (IND-CPA)。
这是Matt Green博士关于PKCS填充与OAEP填充的相关讨论。非常平易近人:A bad couple of years for the cryptographic token industry。
是&#34; AAAAAAAA ......&#34;填充是否正确没有填充java?
可能。我相信它只是一串前导0x00字节的Base64编码。
openssl在C ++代码中做了什么导致结果似乎有填充和时间变化?
使用OAEP。
所以,问题变成了:
openssl做了什么来填充输入以达到所需的长度?
使用OAEP。
问题可能变成:为什么Java不使用它,因为缺少OAEP意味着您可能会泄漏每条加密邮件的信息。