我有以下代码行来生成私钥:
int Xa = randomNo.nextInt(10000);
int Ya = (int) Math.pow(G, Xa) % P;
G
和P
是静态数字。而Xa
是随机生成的。每次运行程序时,它都会为Ya
提供相同的结果。这对Diffie-Hellman来说是否正确?我认为每次运行算法时都必须更改私钥。
答案 0 :(得分:3)
问题是Java中的Random
类有一个构造函数,其中包含一个long
参数(称为 seed ),它允许您启动特定的伪随机数序列方式。
如果您始终使用相同的种子,您将始终获得相同的序列。
要解决此问题,请尝试以下操作:
Random randomNo = new Random(System.nanoTime());
int Xa = randomNo.nextInt(10000);
通过这种方式,种子总是不同的,每次调用上面的行时序列都会改变。
答案 1 :(得分: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
,否则您将无法生成密钥。过程如下:
Ya
(我只是使用此变量名称,因为它是您使用的名称)。Ya
发送给某人。Ya
的人那里收到一些号码(在上面的示例中称为此号码R
。)R
,Xa
和P
计算您将用于加密的对称密钥。 (参见上面的公式SK
)答案 2 :(得分:2)
我认为问题可能是你的指数溢出了两倍,导致无穷大,每次都产生相同的值(除非你很幸运,最终为你的指数返回一个非常低的数字)。 / p>
另外,请务必使用安全随机来获取随机值:
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);
答案 3 :(得分:1)
如果Xa
不同,则只能提供不同的结果。你是如何产生Xa
的价值的?您可能使用了通常需要播种的伪随机生成器。如果每次都使用默认种子(每次都是相同的种子),它将始终返回相同的随机数序列。
尝试使用System.currentTimeMillis();