Java Diffie-Hellman私钥

Java Diffie-Hellman私钥,java,diffie-hellman,Java,Diffie Hellman,我有下面一行代码来生成私钥: int Xa = randomNo.nextInt(10000); int Ya = (int) Math.pow(G, Xa) % P; G和p是静态数字。而Xa是随机生成的。每次我运行该程序时,它都会为Ya提供相同的结果。这对Diffie Hellman正确吗?我认为每次运行算法时都必须更改私钥。问题是Java中的Random类有一个构造函数,它有一个long参数(称为seed),允许您以特定方式启动伪随机数序列 如果始终使用相同的种子,则始终会获得相同的序列

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

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

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

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

如果始终使用相同的种子,则始终会获得相同的序列

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

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

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

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


尝试使用
System.currentTimeMillis()为生成器设定种子

我认为问题可能在于,你的求幂运算溢出了double,结果是无穷大,每次都是相同的值(除非你足够幸运,最终得到的指数返回的数字非常低)

此外,请确保使用安全随机获取随机值:

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);
编辑:带调试的代码(以下内容适用于我):


其他人似乎对你生成的随机数给出了很好的答案,所以我将回答你的问题“这对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的随机对象的地方贴一行吗?编辑过的original@VitoShadow-我已经输出了随机数,它可以工作了。你试过我的答案了吗?你最好使用
    BigInteger
    而不是
    int
    long
    …G和P的值是多少?我认为你的指数溢出了两倍,每次都是无穷大,结果都是一样的。所以如果我理解正确的话-种子现在来自内部时钟吗?我也得到了错误“没有为nextInt(long)找到合适的方法”。是的,这是一个从伪随机数创建随机数的技巧。非常感谢。您介意告诉我,与SecureRandom()相比,使用这个有什么好处吗如上所述?我已将代码编辑为您上面列出的代码,但每次似乎都输出相同的数字。如果这是出于加密目的,您应该使用
    SecureRandom
    ,而不是
    Random
    。干杯@2to1mux-这更清楚了。我一直在网上学习教程。()我有完全相同的代码,只是P是26,G是42。仍然生成相同的数字?(random.nextInt是100)。这是由于代码的第二个问题(刚刚修复了上面的问题),在那里你需要在施放前做模。在上面添加括号使其工作。尝试过了-仍然不走运。我被难住了。查看上面的编辑和调试以及完整的代码..对我有效。上面的代码对我也有效。奇怪。这可能与我在一次求和中做幂和模有关吗?无论如何谢谢@increment1
    SK = (int)Math.pow(R, Xa) % P;