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