Diffie-Hellman Key Exchange Server

manish_iitg excellencetechnologies08 at gmail.com
Tue Dec 9 08:51:22 EST 2008


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.

http://en.wikipedia.org/wiki/Diffie-Hellman

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's receives the client's public key and generates it's Secret
Key.
// Also the server send 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();
	}

}




 
-- 
View this message in context: http://n2.nabble.com/Diffie-Hellman-Key-Exchange-Server-tp1633893p1633893.html
Sent from the Netty User Group mailing list archive at Nabble.com.




More information about the netty-users mailing list