Diffie-Hellman私钥

我有以下代码行来生成私钥:

int Xa = randomNo.nextInt(10000); int Ya = (int) Math.pow(G, Xa) % P; 

GP是静态数字。 而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 ,否则您将无法生成密钥。 过程如下:

  1. 生成Ya (我只是使用这个变量名,因为它是你使用的)。
  2. Ya发送给某人。
  3. 从您发送给Ya的人那里收到一些号码(在上面的示例中称为此号码R )。
  4. 计算您将使用RXaP进行加密的对称密钥。 (参见上面的SK公式)

如果Xa不同,这只能给出不同的结果。 你是如何产生Xa的价值的? 您可能使用了通常需要播种的伪随机生成器。 如果每次都使用默认种子(每次都是相同的种子),它将始终返回相同的随机数序列。

尝试使用System.currentTimeMillis();您的生成器播种System.currentTimeMillis();