我编写的代码能够生成2048位的素数p& q并使用它来加密RSA中的消息。我生成这些数字的方法是使用java.math.BigInteger包的probablePrime()函数。我的问题是这些函数生成的质数在加密方面有多强。
这是我生成这些数字的代码,isPrime只是我编写的一个布尔函数,用于检查数字是否为素数。
BigInteger definitePrime(int bits, Random rnd) {
BigInteger prime = new BigInteger("4");
while (!isPrime (prime)) {
prime = BigInteger.probablePrime(bits, rnd);
}
return prime;
}
答案 0 :(得分:2)
正如Stephen C在his answer中指出的那样,素数可能适用于RSA加密。
我想补充一点,您实际上不应该使用任何Random
实例,而应该只使用您的系统最佳SecureRandom
实现。
new Random()
不是加密随机源,而new SecureRandom()
应该是。{1}}。如果用于素数生成的随机数不是加密安全的,那么攻击者可能有机会根据其他信息(例如弱随机源的时间或先前输出)简单地重新创建那些信息。
你自己正在做“一切”,而你似乎真的想用它来进行严肃的加密。如果你是,那你就错过了一些至关重要的东西,那就是填充方案。
使用BigInteger
方法实现RSA很容易,因此它可以正常工作,但这还不足以使其安全。您需要使用填充方案,如PKCS#1 v1.5(不推荐使用)或PKCS#1 v2 OAEP(推荐)。
不要为您的“手工制作”RSA实现这些填充方案,而是使用Java Cipher
instance为RSA提供这些填充方案:
RSA/ECB/PKCS1Padding
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
答案 1 :(得分:1)
BigInteger.probablePrime()
的{{3}}说:
使用指定的bitLength返回可能为素数的正BigInteger。此方法返回的BigInteger为复合的概率不超过 2 -100 。
2 -100 表示1,267,650,600,228,229,401,496,703,205,376中的一次机会;即在1.267 * 10 30
中的一次机会由于您正在尝试生成2个素数,这意味着您在生成弱RSA密钥对的大约10 30 中有2次机会。
我认为这已经足够了,但是如果你不这么认为那么你可以用BigInteger.isProbablePrime(certainty)
来测试你的优秀候选人,以达到更高的确定性。
我的问题是这些函数生成的素数在加密方面有多强。
我不知道是否有一种数学上严格的方法来量化加密算法的强度。但是上面的分析告诉你给定生成的密钥对弱/容易破解的可能性。
答案 2 :(得分:-1)
如果您使用类似java.util.Random而不是SecureRandom的实例,则生成的素数不安全。您的代码段并未告诉我们您使用的是什么,因此无法验证您的代码。当然,您可能应该只使用JCE生成新的RSA密钥。