4

我有下面的代码行来生成一个私钥:

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

G并且P是静态数字。而Xa随机生成。每次我运行程序时,它都会给我相同的结果Ya。这对 Diffie-Hellman 是否正确?我认为每次运行算法时都必须更改私钥。

4

4 回答 4

3

问题是RandomJava 中的类有一个带有一个long参数(称为种子)的构造函数,它允许您以特定方式启动伪随机数序列。

如果始终使用相同的种子,您将始终获得相同的序列。

要解决此问题,请尝试以下操作:

Random randomNo = new Random(System.nanoTime());
int Xa = randomNo.nextInt(10000);

这样一来,种子总是不同的,每次调用上述行时,顺序都会发生变化。

于 2013-03-18T18:08:29.273 回答
3

其他人似乎对您生成随机数的问题给出了很好的答案,所以我将回答您的问题“这对 Diffie-Hellman 是否正确?”

我认为您对 Diffie-Helman 的理解有点偏离。一方面,您继续使用术语“私钥”,就好像还有一个“公钥”一样。Diffie-Hellman 密钥交换是一种用于交换一个对称密钥的技术。没有私钥和公钥,只有双方将使用的密钥来加密他们的消息。此外,您说这是“生成”密钥的代码。使用 Diffie-Hellman,探戈需要两个人。此代码不足以生成密钥的最终产品。您需要发送Ya给第二方并从第二方取回一些东西以完成该过程。有关更多信息,请参见下文。

您的生成公式Ya是正确的,假设Xa这是应该的。我有点担心你对你应该做什么的理解,Xa因为你在生成Ya. 您需要坚持Xa以创建密钥的最终版本。

生成后Ya,您应该将其发送给另一方。作为回报,对方会给你发回一些号码(我们称之为R)。为了让您创建对称密钥的最终版本(我们称之为SK),您需要将其计算为

SK = (int)Math.pow(R, Xa) % P;

Xa所以简而言之,计算完后不要重新计算Ya,否则将无法生成密钥。过程如下:

  1. 生成Ya(我只是使用这个变量名,因为它是你使用的)。
  2. 送给Ya某个人。
  3. 从您发送给的人那里收到一些号码Ya(在上面的示例中称为此号码R)。
  4. R使用、Xa和计算您将用于加密的对称密钥应该是什么P。(见上面的公式SK
于 2013-03-18T18:24:14.950 回答
2

我认为问题可能是你的指数溢出双倍,导致无穷大,每次都产生相同的值(除非你足够幸运最终为你的指数返回一个非常低的数字)。

另外,请务必使用安全随机来获取您的随机值:

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);
于 2013-03-18T18:14:15.497 回答
1

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

尝试播种你的发电机System.currentTimeMillis();

于 2013-03-18T18:11:23.210 回答