所以我试图使客户端 - 服务器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.5的int
(方法。通过使用二进制平方乘法算法并在每次乘法后减少mod P,您可以确保没有中间值会溢出int
。