使用 BigInteger probablePrime 函数对 RSA 加密安全吗?

Is using the BigInteger probablePrime function safe for RSA encryption?

我编写了一个代码,能够生成 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;
}

BigInteger.probablePrime()javadoc 说:

Returns a positive BigInteger that is probably prime, with the specified bitLength. The probability that a BigInteger returned by this method is composite does not exceed 2-100.

2-100表示1,267,650,600,228,229,401,496,703,205,376中的一次机会;即 ~1.267 * 1030

中有 1 次机会

由于您尝试生成 2 个素数,这意味着您在大约 1030 中有 2 次机会生成弱 RSA 密钥对。

我认为这已经足够好了,但如果您不这么认为,那么您可以使用 BigInteger.isProbablePrime(certainty) 来测试您的主要候选人,以达到更高的确定性。


My question is how strong of an encryption these function generated prime numbers are in terms of encryption.

我不知道是否有数学上严格的方法来量化加密算法的强度。但是上面的分析告诉你给定的生成的密钥对很弱/容易破解的概率。

正如 Stephen C 在 中指出的那样,素数可能适用于 RSA 加密。

加密随机性

我要补充一点,你实际上不应该使用任何 Random 实例,而应该只使用你的系统最好的 SecureRandom 实现。

new Random() 不是密码随机源,而 new SecureRandom() 应该是。如果用于素数生成的随机数在密码学上不安全,那么攻击者可能有机会根据其他信息(例如时间或弱随机源的先前输出)简单地重新创建这些随机数。

没有教材 RSA

你“什么事”都自己做,看来你真的想用它来进行严格的加密。如果你是,你就错过了一些关键的东西,那就是填充方案。

使用 BigInteger 方法很容易实现 RSA 以使其工作,但不足以使其安全。您需要使用 PKCS#1 v1.5(不再推荐)或 PKCS#1 v2 OAEP(推荐)等填充方案。

使用现有的实现

不要为您的“手工”RSA 实施这些填充方案,而是使用 Java 的 Cipher instance 为 RSA 提供这些填充方案:

  • RSA/ECB/PKCS1Padding
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding

如果您使用 java.util.Random 之类的东西而不是 SecureRandom 的实例,则生成的素数是不安全的。您的代码片段没有告诉我们您在使用什么,因此无法验证您的代码。当然,您可能应该只使用 JCE 来生成新的 RSA 密钥。