Sunteți pe pagina 1din 6

Pseudo Code and Supporting Java Code Modules to Implement Diffie-Hellman Key Exchange

Prepared by: Dr. Natarajan Meghanathan Any questions and/or feedback, email: natarajan.meghanathan@jsums.edu
Given below is the pseudo code for the implementation of the Diffie-Hellman algorithm for two users to agree on a shared secret key using public-key encryption. The sequence of actions to be implemented is as follows (Implement the SenderReceiver and ReceiverSender according to this sequence so that they can run in tandem and generate the session key at both ends):

Table 1: Pseudo Code for the Implementation of the Diffie-Hellman Key Exchange Algorithm Steps
I II

Sender Receiver
Input the Diffie-Hellman parameters g, n and a minimum value for the Public_Key_SR Generate a Public_Key_SR and a Private_Key_SR using the Big Integer and RSA method shown before Use the SenderReceiver code module to first send Public_Key_SR as a Big Integer to the ReceiverSender and then receive Public_Key_RS as a Big Integer from ReceiverSender Generate the Diffie-Hellman parameter a as a Big Integer and compute ga mod n as a Big Integer Encrypt ga mod n using Public_Key_RS and generate the cipher Big Integer: E(Public_Key_RS, ga mod n) Use the SenderReceiver code module to first send E(Public_Key_RS, ga mod n) as a Big Integer to the ReceiverSender and then receive E(Public_Key_SR, gb mod n) as a Big Integer from ReceiverSender Decrypt E(Public_Key_SR, gb mod n) using Private_Key_SR and extract gb mod n as a Big Integer Compute (gb mod n)a mod n as a Big Integer and print it. This is the Secret Session key agreed by both sides

Receiver Sender
Input the Diffie-Hellman parameters g, n and a minimum value for the Public_Key_RS Generate a Public_Key_RS and a Private_Key_RS using the Big Integer and RSA method shown before Use the Receiver Sender code module to first receive Public_Key_SR as a Big Integer from Sender Receiver and then send Public_Key_RS as a Big Integer to SenderReceiver Generate the Diffie-Hellman parameter b as a Big Integer and compute gb mod n as a Big Integer Encrypt gb mod n using Public_Key_SR and generate the cipher Big Integer: E(Public_Key_SR, gb mod n) Use the Receiver Sender code module to first receive E(Public_Key_RS, ga mod n) as a Big Integer from Sender Receiver and then send E(Public_Key_SR, gb mod n) as a Big Integer to SenderReceiver Decrypt E(Public_Key_RS, ga mod n) using Private_Key_RS and extract ga mod n as a Big Integer Compute (ga mod n)b mod n as a Secret session and key and print it. This is the Secret Session key agreed by both sides

III

IV

VI

VII

VIII

Note: You can use the Java code modules (for generating a public-private key pair and for sending and receiving Big Integer across a socket) given in the next few pages as part of the code that you develop to implement the Diffie-Hellman key exchange algorithm narrated in the form of steps I through VIII in Table 1 above.

Java Code to Generate a Public Key Private Key Pair The code given below does the following: You can use extend this code to complete the project. It takes two inputs from the user an integer value for a minimum value of the public key and an integer value corresponding to as ASCII value for encryption The code generates two Big Integers, bigB_p and bigB_q, forming the basis for generating the public key and private key. The user input is first tried for a probable public key, if it cannot be a public key the input value is continuously incremented until we can find a public key. Once we find the public key, we use the RSA basics to find the corresponding private key. Using the public key, we encrypt the ASCII value entered by the user and print a Big Integer cipher value. We then decrypt the cipher value using the private key and extract the plaintext integer ASCII value.
import java.util.*; import java.math.BigInteger; class RSAtest{ public static void main(String[] args){ /* generating two random number generators, each with a different seed */ Random rand1 = new Random(System.currentTimeMillis()); Random rand2 = new Random(System.currentTimeMillis()*10); int asciiVal = Integer.parseInt(args[1]); int pubKey = Integer.parseInt(args[0]); /* public key is at least a certain value input by the user */

/* returns a BigInteger that is not prime with probability less than 2^(-100) */ BigInteger bigB_p = BigInteger.probablePrime(32, rand1); BigInteger bigB_q = BigInteger.probablePrime(32, rand2); BigInteger bigB_n = bigB_p.multiply(bigB_q); BigInteger bigB_p_1 = bigB_p.subtract(new BigInteger("1")); //p-1 BigInteger bigB_q_1 = bigB_q.subtract(new BigInteger("1")); //q-1 BigInteger bigB_p_1_q_1 = bigB_p_1.multiply(bigB_q_1); // (p-1)*(q-1) // generating the correct public key

while (true){ BigInteger BigB_GCD = bigB_p_1_q_1.gcd(new BigInteger(""+pubKey)); if (BigB_GCD.equals(BigInteger.ONE)){ break; }

pubKey++; }

BigInteger bigB_pubKey = new BigInteger(""+pubKey); BigInteger bigB_prvKey = bigB_pubKey.modInverse(bigB_p_1_q_1); System.out.println("bigB_p: "+bigB_p); System.out.println("bigB_q: "+bigB_q); System.out.println(" public key : "+bigB_pubKey+" , "+bigB_n); System.out.println(" private key: "+bigB_prvKey+" , "+bigB_n);

/* encrypting an ASCII integer value using the public key and decrypting the cipher value using the private key and extracting the ASCII value back */ BigInteger bigB_val = new BigInteger(""+asciiVal); BigInteger bigB_cipherVal = bigB_val.modPow(bigB_pubKey, bigB_n); System.out.println("ciphertext: "+bigB_cipherVal); BigInteger bigB_plainVal = bigB_cipherVal.modPow(bigB_prvKey, bigB_n); int plainVal = bigB_plainVal.intValue(); System.out.println("plaintext: "+plainVal);

} }

Java Code to Send and Receive Big Integer across a Datagram Socket The code below does the following: The SenderReceiver module first generates a Big Integer and sends it across a Datagram Socket to a ReceiverSender module. The SenderReceiver module then waits to receive a Big Integer from the ReceiverSender module. The name of the machine and the port at which the ReceiverSender is running have to be passed as command-line inputs to the SenderReceiver. The ReceiverSender module first waits to receive a Big Integer from SenderReceiver and then generates another Big Integer to send to the SenderReceiver. The ReceiverSender extracts the IP address of the SenderReceiver and the port to send the reply from the Datagram Packet object received from the SenderReceiver.
import import import import java.math.BigInteger; java.net.*; java.io.*; java.util.*;

class senderReceiverBigInteger{ public static void main(String[] args){

try{ Random rand = new Random(System.currentTimeMillis()); BigInteger bigBSent = new BigInteger(32, rand); DatagramSocket dataSocket = new DatagramSocket(); InetAddress receiverHost = InetAddress.getByName(args[0]); int receiverPort = Integer.parseInt(args[1]); String stringSent = bigBSent+"";

byte[] senderBuffer = stringSent.getBytes(); System.out.println(" byte sent length: "+senderBuffer.length); DatagramPacket packet = new DatagramPacket(senderBuffer, senderBuffer.length, receiverHost, receiverPort); dataSocket.send(packet);

System.out.println(" BigB sent: "+bigBSent);

// to receive

byte[] bufferReceiver = new byte[100];

DatagramPacket packetReceived = new DatagramPacket(bufferReceiver, bufferReceiver.length); dataSocket.receive(packetReceived); String stringReceived = new String(bufferReceiver); BigInteger bigBReceived = new BigInteger(stringReceived.trim());

System.out.println(" bigB received: "+bigBReceived);

dataSocket.close(); } catch(Exception e){e.printStackTrace();}

} }

----import import import import java.math.BigInteger; java.net.*; java.io.*; java.util.*;

class receiverSenderBigInteger{ public static void main(String[] args){ try{ Random rand = new Random(System.currentTimeMillis()*10);

int receiverPort = Integer.parseInt(args[0]); DatagramSocket dataSocket = new DatagramSocket(receiverPort); byte[] bufferReceiver = new byte[100];

DatagramPacket packetReceived = new DatagramPacket(bufferReceiver, bufferReceiver.length); dataSocket.receive(packetReceived); String stringReceived = new String(bufferReceiver); BigInteger bigBReceived = new BigInteger(stringReceived.trim());

System.out.println(" bigB received: "+bigBReceived);

// to reply back InetAddress senderAddress = packetReceived.getAddress(); int senderPort = packetReceived.getPort(); BigInteger bigBSent = new BigInteger(32, rand); String stringSent = bigBSent+"";

byte[] senderBuffer = stringSent.getBytes(); DatagramPacket packetSent = new DatagramPacket(senderBuffer, senderBuffer.length, senderAddress, senderPort); dataSocket.send(packetSent); dataSocket.close(); System.out.println(" byte sent length: "+senderBuffer.length); System.out.println(" BigB sent: "+bigBSent);

} catch(Exception e){e.printStackTrace();} } }

S-ar putea să vă placă și