【发布时间】:2020-01-16 01:48:43
【问题描述】:
我正在使用 BigInteger 的 probablePrime 方法计算两个 2048 位素数,如下所示:BigInteger.probablePrime(2048, new Random());。我们分别称这些素数为p 和q。我正在使用以下代码计算私有指数:BigInteger.TWO.multiply(r).add(BigInteger.ONE).divide(e); 其中e 相当于BigInteger.valueOf(3),r 相当于一个BigInteger,其值为:(p - 1)(q - 1)。
创建加密的 BigInteger 如下:message.modPow(e, r),其中message 是一个 BigInteger。
假设我想加密774356626352684872522728355634287624183747537718011900969524254770659766752605764866132228010801740792162094。这个大整数是“敏捷的棕狐跳过了懒惰的狗”。先转换成二进制,再转换成十进制。我的结果是464326058229369014486528960945777245568243099145851675968955902027904135435059026247893552949145149936678174588724345105141605583511438062567406913039976998983678282605288609470234530610515268764924240227134432014767865301287496131771559993377618477929696113174968779730288058725125905006272019930686696412137679303439126584。
无论我运行上面的代码多少次,它总是加密到相同的精确值。它生成哪个素数似乎并不重要 - 对于特定的 message 值,加密值始终是上述值。
现在这里变得特别特别,如果我生成 512 位素数,结果是独一无二的。每次我运行上述代码,生成 512 位素数而不是 2048 甚至 1024 位素数时,它每次运行都会生成一个唯一的结果。但是,如果我希望生成 1024 位或 2048 位素数,无论生成什么素数,结果总是相同的。
谁能解释为什么会发生这种情况,或者需要对代码进行哪些更改才能使用 2048 位素数生成唯一的加密整数?具体来说,为什么它适用于 512 位或更低位的素数,而不适用于 1024 位或更大位的素数?如果这不是一个结构最完善的问题,我深表歉意,所以如果有什么令人困惑的地方,请随时要求澄清。
谢谢。
编辑:这是产生问题的代码:
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
public class Yeet {
public static void main(String[] args) throws IOException {
int t = (int) (System.currentTimeMillis() / 1000);
byte[] date = new byte[]{
(byte) (t >> 24),
(byte) (t >> 16),
(byte) (t >> 8),
(byte) t,
};
BigInteger p = BigInteger.probablePrime(2048, new SecureRandom(date));
BigInteger q = BigInteger.probablePrime(2048, new SecureRandom(date));
BigInteger e = BigInteger.valueOf(3);
BigInteger r = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
BigInteger message = new BigInteger("774356626352684872522728355634287624183747537718011900969524254770659766752605764866132228010801740792162094");
System.out.println(message.modPow(e, r));
}
}
根据需要多次运行它。它总是产生464326058229369014486528960945777245568243099145851675968955902027904135435059026247893552949145149936678174588724345105141605583511438062567406913039976998983678282605288609470234530610515268764924240227134432014767865301287496131771559993377618477929696113174968779730288058725125905006272019930686696412137679303439126584。现在,如果我们在第 16 行和第 17 行将 2048 替换为 512,则每次运行都会产生一个唯一值...
【问题讨论】:
-
Random的文档非常清楚地表明它不适合这种应用程序,建议您改用SecureRandom。 -
感谢您的回复。我已将 Random 换成了 SecureRandom。不幸的是,问题仍然存在。编辑:将尝试使用当前时间播种。
-
@DavidSchwartz Folks,我更新了帖子以包含我正在使用的重现问题的代码示例。谢谢!
-
@Jason
SecureRandom由操作系统播种,不需要随时间播种。这将增加微不足道的熵。 -
RSA 加密应该是
m.modPow(e,n),其中n是p * q -- 不是r。解密同上,一旦你正确计算了d,如下所示你不会。
标签: java cryptography rsa biginteger key-pair