From: manish_iitg <excellencetechnologies08@gmail.com>
Subject: Diffie-Hellman Key Exchange Server
To: netty-users@lists.jboss.org
Reply-To: netty-users@lists.jboss.org
Date: Tue, 9 Dec 2008 22:51:22 +0900 (KST)
Hello,
I am new to netty, and i am working on a big project which uses netty. I just wanted to share a piece of code that i have written.
This is client server application, in which both client and server agree upon a Secret Key for Encrypting Data.
I just wanted to share this code with you, so that you guys can comment on the implementation and help me improve it. I think newbies to netty learn a lot if we share the way we implement netty for various problems.
// Code for Encryption Client import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; public class EncryptionClient { public static int PORT = 9091; public void createClient() { ChannelFactory factor = new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ClientBootstrap client = new ClientBootstrap(factor); client.getPipeline().addLast("handler", new EncryptionClientHandler()); client.setOption("tcpNoDelay", true); client.setOption("keepAlive", true); client.connect(new InetSocketAddress("127.0.0.1", PORT)); System.out.println("Encryption Client Created"); } }
// Code for client side handler import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import com.excel.encrypt.Skip; @ChannelPipelineCoverage("one") public class EncryptionClientHandler extends SimpleChannelHandler { private KeyPairGenerator kpg; private KeyPair keyPair; private KeyFactory kf; @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // When connection is established with server, the client send it's generated public key try { kpg = KeyPairGenerator.getInstance("DH"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); kpg.initialize(Skip.sDHParameterSpec); keyPair = kpg.genKeyPair(); byte p[] = keyPair.getPublic().getEncoded(); ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(p); e.getChannel().write(buffer); System.out.println("Client Sent Key"); } catch (Exception ee) { ee.printStackTrace(); } } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // When the client receives the server's public key, it calculates the public key ChannelBuffer buffer = (ChannelBuffer) e.getMessage(); if (buffer.capacity() < 1024) { System.out.println("return"); return; } else { System.out.println("client recieved key"); kf = KeyFactory.getInstance("DH"); byte b[] = new byte[buffer.capacity()]; buffer.getBytes(0, b); X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(b); PublicKey theirPublicKey = kf.generatePublic(x509Spec); byte keyBytes[] = keyPair.getPublic().getEncoded(); ChannelBuffer buffer2 = ChannelBuffers.wrappedBuffer(keyBytes); e.getChannel().write(buffer2); KeyAgreement ka = KeyAgreement.getInstance("DH"); ka.init(keyPair.getPrivate()); ka.doPhase(theirPublicKey, true); SecretKey secretKey = ka.generateSecret("Blowfish"); System.out.println("client key " + new String(secretKey.getEncoded())); System.out.println("client key Length" + secretKey.getEncoded().length); e.getChannel().close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { System.out.println("client exception"); e.getCause().printStackTrace(); } }
// Code for server import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.jboss.netty.handler.execution.ExecutionHandler; import org.jboss.netty.handler.execution.MemoryAwareThreadPoolExecutor; @ChannelPipelineCoverage("all") public class EncryptionServer { public static int PORT = 9091; public void createServer() { ChannelFactory factory = new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap server = new ServerBootstrap(factory); server.getPipeline().addLast( "executor", new ExecutionHandler( new MemoryAwareThreadPoolExecutor(16, 0, 0))); server.getPipeline().addLast("handler", new EncryptionServerRequestHandler()); server.setOption("child.tcpNoDelay", true); server.setOption("child.keepAlive", true); server.bind(new InetSocketAddress(PORT)); System.out.println("Encryption Server Created"); } }
// Code for client side handler import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import com.excel.encrypt.Skip; @ChannelPipelineCoverage("all") public class EncryptionServerRequestHandler extends SimpleChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // The server receives the client's public key and generates it's Secret Key. // Also the server sends back it's public as well to the client. ChannelBuffer buffer = (ChannelBuffer) e.getMessage(); if (buffer.capacity() < 1024) { System.out.println("Server Returned"); return; } else { System.out.println("Server Received Key"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); kpg.initialize(Skip.sDHParameterSpec); KeyPair keyPair = kpg.genKeyPair(); KeyFactory kf = KeyFactory.getInstance("DH"); byte b[] = new byte[buffer.capacity()]; buffer.getBytes(0, b); X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(b); PublicKey theirPublicKey = kf.generatePublic(x509Spec); byte keyBytes[] = keyPair.getPublic().getEncoded(); ChannelBuffer buffer2 = ChannelBuffers.wrappedBuffer(keyBytes); ChannelFuture cf = e.getChannel().write(buffer2); KeyAgreement ka = KeyAgreement.getInstance("DH"); ka.init(keyPair.getPrivate()); ka.doPhase(theirPublicKey, true); SecretKey secretKey = ka.generateSecret("Blowfish"); System.out.println("Server key " + new String(secretKey.getEncoded())); System.out.println("Server key Length" + secretKey.getEncoded().length); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { System.out.println("server"); e.getCause().printStackTrace(); } }
Comments