Diffie Hellman加密公钥给出了错误的值



所以我试图使客户端 - 服务器diffie hellman加密。 我使用这个:serverPublicKey = (int)Math.pow(generator,serverPrivateKey)%prime;生成服务器的公钥,这个:clientPublicKey = (int)Math.pow(generator,clientPrivateKey)%prime;生成客户端的公钥。

当我将服务器的公钥发送到客户端时,一切都很好。 通常给出一个 2 位整数(例如 34(。 但是当我每次将客户端的公钥发送到服务器时,我都会将这样的大数字作为:167772160

这是我的代码

服务器端

int clientPublicKey;
int serverPrivateKey;
int serverPublicKey;
int prime = rand.nextInt(100); 
int generator = rand.nextInt(20);
//sending generator and prime to client
IntToClient.writeInt(prime);//1
IntToClient.writeInt(generator);//2
System.out.println("sent to client Prime :"+prime);
System.out.println("sent to client Generator :"+generator);
System.out.println("Server's private key: ");
serverPrivateKey = sc.nextInt();
//server's public key
serverPublicKey = (int)Math.pow(generator,serverPrivateKey)%prime;
System.out.println("Server sends in public --> "+ serverPublicKey);
IntToClient.writeInt(serverPublicKey);//3
clientPublicKey = IntFromClient.readInt();//4
System.out.println("Client sent public key --> "+ clientPublicKey);

客户端

int prime;
int generator;
int clientPrivateKey;
int clientPublicKey;
int serverPublicKey;
//get random prime and generator from server
prime = IntFromServer.readInt();//1
generator = IntFromServer.readInt();//2
System.out.println("Prime :"+prime);
System.out.println("Generator :"+generator);
//read server's public key
serverPublicKey = IntFromServer.readInt();//3
System.out.println("Server sent public key --> "+ serverPublicKey);
//clients private key
System.out.println("Client's private key: ");
clientPrivateKey = sc.nextInt();
//client's public key
clientPublicKey = (int)Math.pow(generator,clientPrivateKey)%prime;
System.out.println("Client sends in public --> "+ clientPublicKey);
IntToServer.writeInt(clientPublicKey);//4`

所以当我运行它时,我从服务器获取这个

sent to client Prime :44 sent to client Generator :3 Server's private key: 45 Server sends in public --> 23 Client sent public key --> 167772160

而这来自客户

Prime :44 Generator :3 Server sent public key --> 23 Client's private key: 87 Client sends in public --> 23

如果您通过管道发送值(套接字?命名管道?串行端口?

IntToServer.writeInt(clientPublicKey);

。服务器读取另一个值而不是发送的值:

ClientFromClient.readInt();

。那么显然你的管道没有得到很好的实现。显示的所有加密计算都是无用的,不需要解决此问题。

即使这些小数字仍然太大,如果不特别小心,就无法处理。Math.pow()不应在任何地方使用。它将操作数转换为double并返回double结果。但是double只有 52 位的正值精度,而 345已经是 72 位整数。

相反,你可以用简单或困难的方式做到这一点。简单的方法是仅在学习练习中使用BigInteger类及其方法。特别是,您希望对所有模幂使用BigInteger.modPow

还有一个更难的方法。对于这么小的整数,可以实现你自己的模幂mod P(P是模,是一个小于215.5int(方法。通过使用二进制平方乘法算法并在每次乘法后减少mod P,您可以确保没有中间值会溢出int

最新更新