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
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
00073 int clientKeyLength = in.readInt();
00074 byte[] clientBytes = new byte[clientKeyLength];
00075 in.readFully(clientBytes);
00076 JCODHPublicKey clientPublicKey = new JCODHPublicKey(clientBytes);
00077
00078
00079 JCODHPublicKey serverPublicKey = serverKeyPair.getPublic();
00080 byte[] serverBytes = serverPublicKey.getEncoded();
00081 out.writeInt(serverBytes.length);
00082 out.write(serverBytes);
00083
00084
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
00098
00099
00100
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
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
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
00148 JCODHPublicKey clientPublicKey = clientKeyPair.getPublic();
00149 byte[] myBytes = clientPublicKey.getEncoded();
00150 out.writeInt(myBytes.length);
00151 out.write(myBytes);
00152
00153
00154 int serverLength = in.readInt();
00155 byte[] serverBytes = new byte[serverLength];
00156 in.readFully(serverBytes);
00157 JCODHPublicKey serverPublicKey = new JCODHPublicKey(serverBytes);
00158
00159
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
00173
00174
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
00188 out.close();
00189 in.close();
00190 return secret;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206