Diffie-Hellman私钥
我有以下代码行来生成私钥:
int Xa = randomNo.nextInt(10000); int Ya = (int) Math.pow(G, Xa) % P;
G
和P
是静态数字。 而Xa
是随机生成的。 每次我运行程序时,它都会给我相同的结果。 这对Diffie-Hellman来说是否正确? 我认为每次运行算法时都必须更改私钥。
我认为问题可能是你的指数溢出了两倍,导致无穷大,每次都产生相同的值(除非你很幸运,最终为你的指数返回一个非常低的数字)。
此外,请务必使用安全随机来获取随机值:
Random random = new SecureRandom(); // If you use more than 100 here, then // with your value of 486 for G you will // end up with infinity when doing Math.pow(G,Xa). // Of course, this does not provide enough possible // values to be cryptographically secure. int Xa = random.nextInt(100); int Ya = (int) (Math.pow(G, Xa) % P);
编辑:调试代码(以下适用于我):
double G = 42; int P = 26; Random random = new SecureRandom(); int Xa = random.nextInt(100); double val = Math.pow(G, Xa); System.out.println("Xa: " + Xa); System.out.println("(double) Math.pow: " + val + " (int): " + (int) val); int Ya = (int) (val % P); System.out.println("Ya: " + Ya);
问题是Java中的Random
类有一个带有一个long
参数(称为种子 )的构造函数,它允许您以特定方式启动伪随机数序列。
如果您始终使用相同的种子,您将始终获得相同的序列。
要解决此问题,请尝试以下操作:
Random randomNo = new Random(System.nanoTime()); int Xa = randomNo.nextInt(10000);
这样,种子总是不同的,每次调用上面的行时序列都会改变。
其他人似乎已经对你生成的随机数问题给出了很好的答案,所以我会回答你的问题“这对Diffie-Hellman来说是否正确?”
我认为你对Diffie-Helman的理解有点偏。 首先,你继续使用术语“私钥”,好像还有一个“公钥”。 Diffie-Hellman密钥交换是用于交换一个对称密钥的技术。 没有私钥和公钥,只有一个密钥,双方将用于加密他们的消息。 而且,你说这是“生成”密钥的代码。 有了Diffie-Hellman,它需要两个探戈。 此代码不足以生成密钥的最终产品。 您需要将Ya
发送给第二方并从该第二方获取回复以完成该过程。 有关详细信息,请参见下文
你的生成Ya
公式是正确的,假设Xa
是它应该是的。 我有点担心你对你应该用Xa
做什么的理解,因为你在生成Ya
之后将它重新分配给一个随机值。 您需要依靠Xa
才能创建密钥的最终版本。
在您生成Ya
,您应该将其发送给另一方。 另一方会回复给你一些号码(让我们称之为R
)。 为了让您创建对称密钥的最终版本(让我们称之为SK
),您需要将其计算为
SK = (int)Math.pow(R, Xa) % P;
因此,简而言之,在计算Ya
之后不要重新计算Xa
,否则您将无法生成密钥。 过程如下:
- 生成
Ya
(我只是使用这个变量名,因为它是你使用的)。 - 将
Ya
发送给某人。 - 从您发送给
Ya
的人那里收到一些号码(在上面的示例中称为此号码R
)。 - 计算您将使用
R
,Xa
和P
进行加密的对称密钥。 (参见上面的SK
公式)
如果Xa
不同,这只能给出不同的结果。 你是如何产生Xa
的价值的? 您可能使用了通常需要播种的伪随机生成器。 如果每次都使用默认种子(每次都是相同的种子),它将始终返回相同的随机数序列。
尝试使用System.currentTimeMillis();
您的生成器播种System.currentTimeMillis();