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

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       // Wait for network connection
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       // Receive their public key
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       // Respond with my public key
00098       byte[] myBytes = keyPair.getPublic().getEncoded();
00099       out.writeInt(myBytes.length);
00100       out.write(myBytes);
00101       
00102       // Generate shared secret
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       // Clean up
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       // Create Diffie-Hellman key pair
00144       KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "BC");
00145       kpg.initialize(skipParams);
00146       this.keyPair = kpg.genKeyPair();
00147 
00148       // Open the network connection
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       // Send my public key
00156       byte[] myBytes = keyPair.getPublic().getEncoded();
00157       out.writeInt(myBytes.length);
00158       out.write(myBytes);
00159       
00160       // Receive their public key
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       // Generate the secret value
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       // Clean up
00179       out.close();
00180       in.close();
00181       return secret;
00182     }
00183   }
00184 }
00185 //Listening on port 8765
00186 //Server ka=KeyAgreement msec: 6677
00187 //Server ka.init msec: 14
00188 //Server ka.doPhase msec: 503
00189 //Server ka.generateSecret msec: 1
00190 //Server secret:AItNLhor/hXuYq0uyGykIHaBv+4Yjul0eU224Lc55ISayBq1GZ5/jpruaRLeiad6846qyh16vE52x/i3K7/dmYqQIY3iAhTKS/JQs5jZjhjfib2K/shzQGK1dnkA2pIYMQhWP5YOjz5zK3VGbg1QYA8BIraS0Or3+02nE/aNlmp9
00191 //
00192 //Client ka=KeyAgreement.getInstance: 6696
00193 //Client ka.init: 13
00194 //Client ka.doPhase: 381
00195 //Client ka.generateSecret: 1
00196 //Client secret: AItNLhor/hXuYq0uyGykIHaBv+4Yjul0eU224Lc55ISayBq1GZ5/jpruaRLeiad6846qyh16vE52x/i3K7/dmYqQIY3iAhTKS/JQs5jZjhjfib2K/shzQGK1dnkA2pIYMQhWP5YOjz5zK3VGbg1QYA8BIraS0Or3+02nE/aNlmp9