JCOSkip.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.KeyFactory;
00009 import java.security.KeyPair;
00010 import java.security.KeyPairGenerator;
00011 import java.security.Provider;
00012 import java.security.PublicKey;
00013 import java.security.Security;
00014 import java.security.spec.X509EncodedKeySpec;
00015
00016 import javax.crypto.KeyAgreement;
00017 import javax.crypto.spec.DHParameterSpec;
00018
00019 import org.bouncycastle.jce.provider.BouncyCastleProvider;
00020
00021 import edu.virtualschool.jco.JCOBase64;
00022 import edu.virtualschool.jwaa.IntervalTimer;
00023
00030 public class JCOSkip
00031 {
00032
00033 private static final BigInteger skipP = new BigInteger(
00034 "f488fd584e49dbcd20b49d349107366b336c380d451d0f7c88b31c7c5b2d8ef6"+
00035 "f3c923c043f0a55b188d8ebb558cb85d38d334fd7c175743a31d186cde33212c"+
00036 "b52aff3ce1b1294018118d7c84a70a72d686c40319c807297aca950cd9968fab"+
00037 "d00a509b0246d3083d66a45d419f9c7cbd894b221926baaba25ec355e92f78c7", 16);
00038
00039 private static final BigInteger skipG = BigInteger.valueOf(2);
00040
00041 private static final DHParameterSpec skipParams =
00042 new DHParameterSpec(skipP, skipG);
00043
00044 public static void main(String[] args) throws Exception
00045 {
00046 Server.main(new String[] { "8081" });
00047 Client.main(new String[] {"localhost", "8081"});
00048 return;
00049 }
00057 public static class Server
00058 {
00059 final private KeyPair keyPair;
00060 final private DataOutputStream out;
00061 final private DataInputStream in;
00062
00063 private final static Provider provider = new BouncyCastleProvider();
00064 static { Security.addProvider(provider); }
00065
00066 public static void main(String[] args) throws Exception
00067 {
00068 int port = Integer.parseInt(args[0]);
00069 Server server = new Server(port);
00070 byte[] secret = server.getSecretKey();
00071 System.out.println("Server secret:"+JCOBase64.encode(secret));
00072 }
00073 public Server(int port) throws Exception
00074 {
00075 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
00076 kpg.initialize(skipParams);
00077 this.keyPair = kpg.genKeyPair();
00078
00079
00080 ServerSocket ss = new ServerSocket(port);
00081 System.out.println("Listening on port " + port);
00082 Socket s = ss.accept();
00083
00084 this.out = new DataOutputStream(s.getOutputStream());
00085 this.in = new DataInputStream(s.getInputStream());
00086 }
00087 public byte[] getSecretKey() throws Exception
00088 {
00089
00090 int theirLength = in.readInt();
00091 byte[] theirBytes = new byte[theirLength];
00092 in.readFully(theirBytes);
00093 KeyFactory kf = KeyFactory.getInstance("DH", "BC");
00094 X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(theirBytes);
00095 PublicKey theirPublicKey = kf.generatePublic(x509Spec);
00096
00097
00098 byte[] myBytes = keyPair.getPublic().getEncoded();
00099 out.writeInt(myBytes.length);
00100 out.write(myBytes);
00101
00102
00103 IntervalTimer t = new IntervalTimer();
00104 KeyAgreement ka = KeyAgreement.getInstance("DH", "BC");
00105 System.err.println("Server ka=KeyAgreement msec: "+t);
00106 ka.init(keyPair.getPrivate());
00107 System.err.println("Server ka.init msec: "+t);
00108 ka.doPhase(theirPublicKey, true);
00109 System.err.println("Server ka.doPhase msec: "+t);
00110 byte[] secret = ka.generateSecret();
00111 System.err.println("Server ka.generateSecret msec: "+t);
00112
00113
00114 out.close();
00115 in.close();
00116 return secret;
00117 }
00118 }
00124 public static class Client
00125 {
00126 final private KeyPair keyPair;
00127 final private DataOutputStream out;
00128 final private DataInputStream in;
00129
00130 private final static Provider provider = new BouncyCastleProvider();
00131 static { Security.addProvider(provider); }
00132
00133 public static void main(String[] args) throws Exception
00134 {
00135 String host = args[0];
00136 int port = Integer.parseInt(args[1]);
00137 Client client = new Client(host, port);
00138 byte[] secret = client.getSecretKey();
00139 System.out.println("Client secret: " + JCOBase64.encode(secret));
00140 }
00141 public Client(String host, int port) throws Exception
00142 {
00143
00144 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "BC");
00145 kpg.initialize(skipParams);
00146 this.keyPair = kpg.genKeyPair();
00147
00148
00149 Socket s = new Socket(host, port);
00150 this.out = new DataOutputStream(s.getOutputStream());
00151 this.in = new DataInputStream(s.getInputStream());
00152 }
00153 public byte[] getSecretKey() throws Exception
00154 {
00155
00156 byte[] myBytes = keyPair.getPublic().getEncoded();
00157 out.writeInt(myBytes.length);
00158 out.write(myBytes);
00159
00160
00161 byte[] theirBytes = new byte[in.readInt()];
00162 in.readFully(theirBytes);
00163 KeyFactory kf = KeyFactory.getInstance("DH", "BC");
00164 X509EncodedKeySpec theirSpec = new X509EncodedKeySpec(theirBytes);
00165 PublicKey theirPublicKey = kf.generatePublic(theirSpec);
00166
00167
00168 IntervalTimer t = new IntervalTimer();
00169 KeyAgreement ka =KeyAgreement.getInstance("DH", "BC");
00170 System.err.println("Client ka=KeyAgreement.getInstance: "+t);
00171 ka.init(keyPair.getPrivate());
00172 System.err.println("Client ka.init: "+t);
00173 ka.doPhase(theirPublicKey, true);
00174 System.err.println("Client ka.doPhase: "+t);
00175 byte[] secret = ka.generateSecret();
00176 System.err.println("Client ka.generateSecret: "+t);
00177
00178
00179 out.close();
00180 in.close();
00181 return secret;
00182 }
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196