Java RSA加密不可重复?
我用RSA公钥加密时遇到问题。下面是重现问题的JUnit代码示例:Java RSA加密不可重复?,java,cryptography,rsa,Java,Cryptography,Rsa,我用RSA公钥加密时遇到问题。下面是重现问题的JUnit代码示例: public class CryptoTests { private static KeyPair keys; @BeforeClass public static void init() throws NoSuchAlgorithmException{ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); SecureRandom ra
public class CryptoTests {
private static KeyPair keys;
@BeforeClass
public static void init() throws NoSuchAlgorithmException{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = CryptoUtils.getSecureRandom();
keyGen.initialize(2176, random);
keys = keyGen.generateKeyPair();
}
@Test
public void testRepeatabilityPlainRSAPublic() throws EdrmCryptoException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
byte[] plaintext = new byte [10];
Random r = new Random();
r.nextBytes(plaintext);
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, keys.getPublic());
byte[] encrypted1 = rsa.doFinal(plaintext);
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, keys.getPublic());
byte[] encrypted2 = rsa.doFinal(plaintext);
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, keys.getPublic());
byte[] encrypted3 = rsa.doFinal(plaintext);
assertArrayEquals(encrypted1, encrypted2);
assertArrayEquals(encrypted1, encrypted3);
}
}
结果如何?断言失败了
为什么会出现这种行为?根据我的加密类的记忆,任何密钥都可以用于加密。然而,这并不是这里发生的事情。
我用私钥测试了同样的东西,得到了一个可重复的输出
如果出于某种原因,使用公钥的RSA加密被禁止,那么为什么我没有得到异常
我必须做什么才能得到可重复的结果
另外,我的JDK是1.6.0_22,运行在Ubuntu10.10机器上。我猜它正在应用随机填充,正是为了让它更安全。从:
由于RSA加密是一种确定性加密算法,即没有随机组件,攻击者可以通过加密公钥下可能的明文并测试它们是否等于密文,成功地对密码系统发起选定的明文攻击。如果攻击者即使知道或选择了相应的明文,也无法区分两种加密,则称密码系统为语义安全。如上所述,没有填充的RSA在语义上是不安全的
为了避免这些问题,实际的RSA实现通常会在加密值m之前将某种形式的结构化随机填充嵌入其中。这种填充确保m不属于不安全的明文范围,并且给定的消息一旦填充,将加密为大量可能的密文之一
您可以通过使用字符串RSA/ECB/NoPadding初始化密码来确认正在添加随机填充。现在,您应该看到,密文在每种情况下都是相同的,尽管出于另一位回答者所述的原因,您实际上不应该这样做。要在Jon的回答中添加额外的细节: 当您执行Cipher.getInstance时。。。正如您可能已经收集到的,您有许多选择。指定这些是什么 您要求的RSA默认为RSA,引用wikipedia文章: 有两种加密方案 和解密: RSAES-OAEP:改进的加密/解密方案;基于 最优非对称加密 Mihir提出的填充方案 贝拉尔和菲利普·罗格威。 RSAES-PKCS1-v1_5:旧的加密/解密方案作为第一个 在PKCS1的1.5版中标准化。
有关上述填充方案的详细信息,请参见RSALab。+1比meYes快一分钟,而且解释得更好-真正重要的是它是否解密为相同的原始明文。p.s。我使用了BouncyCastle提供程序,现在我的测试成功了。测试成功是一个非常糟糕的迹象,因为RSA加密应该是随机的。必须将OEAP填充与RSA加密结合使用。教科书中的RSA和PKCS1 v1.5填充都不安全。需要强调的是,RSAES-PKCS1-v1_5允许实际攻击,因此不应使用它。RSAES-OAEP是一条路要走。