Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

JCODHKeyExchange.java

00001 package edu.virtualschool.jco.unfinished;
00002 
00003 import java.io.DataInputStream;
00004 import java.io.DataOutputStream;
00005 import java.math.BigInteger;
00006 import java.net.ServerSocket;
00007 import java.net.Socket;
00008 import java.security.SecureRandom;
00009 
00010 import javax.crypto.spec.DHParameterSpec;
00011 
00012 import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
00013 import org.bouncycastle.crypto.agreement.DHAgreement;
00014 import org.bouncycastle.crypto.generators.DHKeyPairGenerator;
00015 import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
00016 import org.bouncycastle.crypto.params.DHKeyGenerationParameters;
00017 import org.bouncycastle.crypto.params.DHKeyParameters;
00018 import org.bouncycastle.crypto.params.DHParameters;
00019 import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
00020 import org.bouncycastle.crypto.params.DHPublicKeyParameters;
00021 
00022 import edu.virtualschool.jco.JCOBase64;
00023 import edu.virtualschool.jwaa.IntervalTimer;
00024 
00025 
00030 public class JCODHKeyExchange
00031 {
00032   private static final BigInteger skipP = new BigInteger(
00033     "f488fd584e49dbcd20b49d349107366b336c380d451d0f7c88b31c7c5b2d8ef6"+
00034     "f3c923c043f0a55b188d8ebb558cb85d38d334fd7c175743a31d186cde33212c"+
00035     "b52aff3ce1b1294018118d7c84a70a72d686c40319c807297aca950cd9968fab"+
00036     "d00a509b0246d3083d66a45d419f9c7cbd894b221926baaba25ec355e92f78c7", 16);
00037 
00038   private static final BigInteger skipG = BigInteger.valueOf(2);
00039 
00040   public static final DHParameterSpec skipParams = 
00041     new DHParameterSpec(skipP, skipG);
00042     
00043   public final static   int port = 8765;
00049   public static class Server
00050   {
00051     final DataOutputStream out;
00052     final DataInputStream in;
00053     final JCODHKeyPair serverKeyPair = new JCODHKeyPair(skipP, skipG);
00054     
00055     public static void main(String[] args) throws Exception
00056     {
00057       Server server = new Server(port);
00058       byte[] secret = server.getSessionKeyBytes();
00059       System.out.println("Server secret:"+JCOBase64.encode(secret));
00060     }
00061     public Server(int port) throws Exception
00062     {
00063       // Wait for network connection
00064       ServerSocket ss = new ServerSocket(port);
00065       System.out.println("Listening on port " + port);
00066       Socket s = ss.accept();
00067       this.out = new DataOutputStream(s.getOutputStream());
00068       this.in = new DataInputStream(s.getInputStream());
00069     }
00070     public final byte[] getSessionKeyBytes() throws Exception
00071     {
00072       // Receive client public key
00073       int clientKeyLength = in.readInt();
00074       byte[] clientBytes = new byte[clientKeyLength];
00075       in.readFully(clientBytes);
00076       JCODHPublicKey clientPublicKey = new JCODHPublicKey(clientBytes);
00077       
00078       // Respond with server public key
00079       JCODHPublicKey serverPublicKey = serverKeyPair.getPublic();
00080       byte[] serverBytes = serverPublicKey.getEncoded();
00081       out.writeInt(serverBytes.length);
00082       out.write(serverBytes);
00083       
00084       // Generate shared secret
00085       AsymmetricKeyParameter akp = clientPublicKey.getParameters();
00086       DHKeyParameters dkp = (DHKeyParameters)akp;
00087       DHParameters  p = dkp.getParameters();
00088       SecureRandom r = new SecureRandom();
00089       DHKeyGenerationParameters params = new DHKeyGenerationParameters(r, p);
00090       DHKeyPairGenerator kpGen = new DHKeyPairGenerator();
00091       kpGen.init(params);
00092       
00093       AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
00094       DHPublicKeyParameters pubP = (DHPublicKeyParameters)pair.getPublic();
00095       DHPrivateKeyParameters prvP = (DHPrivateKeyParameters)pair.getPrivate();
00096       
00097 //    Listening on port 8765
00098 //    Server calculateMessage:9408 msec
00099 //    Server calculateAgreement:364 msec
00100 //    Server secret:ANozRjQvpOiaTgEHS46yqrNJBMWk93F5EfS/Vw2UhAVUW/mUzKoMyX4kPd95g3vF3BwTkmMm5TspDN32YQP7/1p9lVvW4tuIadqpqvWO8z94EIRbkus8VyMZq21OwwgHOHYNiAR0oKY5AlxMTf2O+buWJGjIeMGZulgBhzQQzkej
00101       
00102       IntervalTimer t = new IntervalTimer();
00103       DHAgreement dha = new DHAgreement();
00104       System.err.println("Server dha=DHAgreement:"+t);
00105       dha.init(prvP);
00106       System.err.println("Server dha.init:"+t);
00107       BigInteger  message = dha.calculateMessage();
00108       System.err.println("Server dha.calculateMessage:"+t);
00109       BigInteger  agreement = dha.calculateAgreement(pubP, message);
00110       System.err.println("Server dha.calculateAgreement:"+t);
00111       byte[] secret = agreement.toByteArray();
00112       
00113       // Clean up
00114       out.close();
00115       in.close();
00116       return secret;
00117     }
00118   }
00124   public static class Client
00125   {
00126     final DataOutputStream out;
00127     final DataInputStream in;
00128     final JCODHKeyPair clientKeyPair = new JCODHKeyPair(skipP, skipG);
00129 
00130     
00131     public static void main(String[] args) throws Exception
00132     {
00133       String host = "localhost";
00134       Client client = new Client(host, port);
00135       byte[] secret = client.getSessionKeyBytes();
00136       System.out.println("Client secret: " + JCOBase64.encode(secret));
00137     }
00138     public Client(String host, int port)  throws Exception
00139     {
00140     // Open the network connection
00141       Socket s = new Socket(host, port);
00142       this.out = new DataOutputStream(s.getOutputStream());
00143       this.in = new DataInputStream(s.getInputStream());
00144     }
00145     public byte[] getSessionKeyBytes() throws Exception
00146     {
00147       // Send client public key
00148       JCODHPublicKey clientPublicKey = clientKeyPair.getPublic();
00149       byte[] myBytes = clientPublicKey.getEncoded();
00150       out.writeInt(myBytes.length);
00151       out.write(myBytes);
00152       
00153       // Receive their public key
00154       int serverLength = in.readInt();
00155       byte[] serverBytes = new byte[serverLength];
00156       in.readFully(serverBytes);
00157       JCODHPublicKey serverPublicKey = new JCODHPublicKey(serverBytes);
00158           
00159       // Generate the secret value
00160       AsymmetricKeyParameter akp = serverPublicKey.getParameters();
00161       DHKeyParameters dkp = (DHKeyParameters)akp;
00162       DHParameters  p = dkp.getParameters();
00163       SecureRandom r = new SecureRandom();
00164       
00165       DHKeyGenerationParameters params = new DHKeyGenerationParameters(r, p);
00166       DHKeyPairGenerator kpGen = new DHKeyPairGenerator();
00167       kpGen.init(params);
00168       AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
00169       DHPublicKeyParameters pubP = (DHPublicKeyParameters)pair.getPublic();
00170       DHPrivateKeyParameters prvP = (DHPrivateKeyParameters)pair.getPrivate();
00171       
00172 //    Client calculateMessage:7512 msec
00173 //    Client calculateAgreement:753 msec
00174 //    Client secret: GksSntlQZSUn4HLbmLY3NV4CVO7txRaA2Iv+M7/oveW5GFzDkZYvyAcH46hpFHmbP9GwMGxj73HOFSUVW3oq9EcbObkRb++3RUW+amb9h+2t0vkggFLKc/SLik95RHwwu7Yx27sfKrHs5ivEWdkF+9tA+OUJ7RTPHsBmID/0zMg=
00175 
00176       IntervalTimer t = new IntervalTimer();
00177       DHAgreement dha = new DHAgreement();
00178       System.err.println("Client dha=DHAgreement msec:"+t);
00179       dha.init(prvP); 
00180       System.err.println("Client dha.init msec:"+t);
00181       BigInteger  message = dha.calculateMessage();
00182       System.err.println("Client dha.calculateMessage msec:"+t);
00183       BigInteger  agreement = dha.calculateAgreement(pubP, message);
00184       System.err.println("Client dha.calculateAgreement msec:"+t);
00185       byte[] secret = agreement.toByteArray();
00186       
00187       // Clean up
00188       out.close();
00189       in.close();
00190       return secret;
00191     }
00192   }
00193 }
00194 //Listening on port 8765
00195 //Server dha=DHAgreement:22
00196 //Server dha.init:28
00197 //Server dha.calculateMessage:25052
00198 //Server dha.calculateAgreement:747
00199 //Server secret:AJvxbF2BZH+fgCxuOpixa6IQl7Mdr4qhsHJOXO+Mhffg31EAy0Hu9hUkY9uNgA6XBnXxBPs8BNjSYK/SlA2RvJL5L5PmHKWYqKuF9XQP4SbhbD98K2InOW8rs47i1LP3Oo0eVmG4HESuQDErGxUMrIFldRVy4TohGUSb0EVQHoiO
00200 
00201 //Client dha=DHAgreement msec:7
00202 //Client dha.init msec:39
00203 //Client dha.calculateMessage msec:35524
00204 //Client dha.calculateAgreement msec:370
00205 //Client secret: ALj9pDOn1QLHsvork6Lg0jEt1xsLQc1w282HQc/ZvHI7ea4sJO/PSVqE9t6ipGfuSJJEAJ8jQfqAViGS0losaX+3Ik6L238trB9tOnWseWA8MYZezqZBfyB0Af+fdi7MOzAwsweKr2JarclfbcLIH0/asLSXu5NdPcNlOv6XAlZr
00206