Cryptographic key exchange I initially posted this on StackOverflow, and was redirected here.
I have been playing around with Bouncy Castle (Java) for the last few days, and I've reached the point where I believe I can securely exchange secret keys with a Diffie-Hellman exchange.

Having read many posts underlining the difficulty of properly implementing a cryptographic exchange, I would like your honest opinion on my work.
All the underlying cipher operations are based on Bouncy Castle and may therefore be deemed reliable.

String message = "Hello World";

AESCipher aes_client = new AESCipher(256);
RSACipher rsa_server = new RSACipher(2048);

// (Public key sent over the wire)
RSACipher rsa_client = new RSACipher(rsa_server.getPublicKey().getModulus(),
                                     rsa_server.getPublicKey().getExponent());

// The client encodes his AES key with the RSA public key:
byte[] aes_key = rsa_client.encode(aes_client.getKeyBytes());
byte[] aes_iv = rsa_client.encode(aes_client.getInitializationVector());

// (Data sent back over the wire)
byte[] decoded_aes_key = rsa_server.decode(aes_key);
byte[] decoded_aes_iv = rsa_server.decode(aes_iv);

// The server creates an AES server which uses the client key:
AESCipher aes_server = new AESCipher(decoded_aes_key, decoded_aes_iv);

byte[] encoded_message = aes_client.encode(message.getBytes());
byte[] decoded_message = aes_server.decode(encoded_message);

System.out.println(new String(decoded_message));


Can this exchange be considered safe? Should I be sticking with SSL Sockets, eventhough it'd hurt to thrash my hard work?
Thanks in advance for your input!

(By the way, my Bouncy-Castle-Wrapping-Library is totally open-source, so just let me know if you want the repository's URL.)
It's very difficult to answer you, because what you've posted is a test-bed where your byte arrays are passed around in the context of a high-level language, as opposed to a real situation where you'd have (at the very least) two processes communicating down a pipe, TCP socket or similar. The details of how you do this are crucial; getting them wrong will destroy your security just as easily as if you get the crypto wrong.

I haven't thought about your code very much, but these questions immediately come to mind:


How are you sending and receiving data over the wire - how are your packets delimited and parsed?
How are the crypto keys being generated - specifically, what's their random source? 
How are keys being stored at either end?
What RSA padding and AES mode are you using?
How do you know that the key you've got really belongs to the person you think it does, and not some man in the middle? In other words, how do you establish trust in that key?


As others have said, you should be reusing an existing library to use a well-established protocol. You might care to read the stick figure guide to AES: pay particular note to the Foot-Shooting Prevention Agreement; what goes for not inventing your own crypto algorithms, also goes for protocols.