Tuesday, July 31, 2007

August 8th Report

Secure Message Transfer Between Java and C++

Scenario:

We are developing an application which require secure message transfer between Naradabrokering (java based messaging substrate) and C++ client application. The communications between the entities uses a custom publish/subscribe messaging protocol to get better performance. (No XML processing)

JDK has a built in support for security features such as certificate handling, encryption and signing. However, to get those functionalities in C++ a separate library needs to be installed. For this we used Openssl (http://www.openssl.org/) To develop applications it is required to have the development files of the openssl and the installation is different according to the underlying operating system. For my machine running Ubuntu 2.6.15-28-386 it is simply;

apt-get install libssl0.9.7
apt-get install libssl-dev

Following sections of shows the code fragments that we can use to encrypt/decrypt messages (bytes) both in Java and C++. The algorithm used for the encryption is AES (http://en.wikipedia.org/wiki/Advanced_Encryption_Standard)


Encryption in JAVA

In java the encryption is handled by the provided javax.crypto.Cipher class. The following code fragment shows the encryption in Java.

byte[] bytesToEncrypt = /*Bytes to be encrypted*/
byte[] encBytes = null; /*Encrypted Bytes*/

/**
* Create a Cipher by specifying the following parameters a. Algorithm
* name - here it is AES */

Cipher aesCipher;
try {
aesCipher = Cipher.getInstance(Constants.AES_ALGO);

aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
encBytes = aesCipher.doFinal(msg.getBytes());
} catch (Exception e) {

throw new ClarensException(

"Error encrypt message using secret key",e);

}

These bytes are then transferred to the C++ client using socket based communication channel.

Decryption in C++

Openssl provides a set of libraries for handling the decryption and the following utility function shows how we can use those to decrypte the received set of bytes.

bool
SecurityUtil::decryptAES(const unsigned char *in,int inputLength ,unsigned char *out,int &outputLength, string aesKey){

int olen, tlen, n;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (& ctx);
EVP_DecryptInit (& ctx, EVP_aes_128_ecb (), (unsigned char *)aesKey.c_str(), NULL);

olen=0; tlen=0;

if (EVP_DecryptUpdate (& ctx, out, & olen, (const unsigned char*)in,inputLength) != 1)
{
cerr<<"error in decrypt update"< return false;
}

if (EVP_DecryptFinal(& ctx, out + olen, & tlen) != 1)
{
cerr<<"error in decrypt final"< return false;
}

olen += tlen;
outputLength=olen;

EVP_CIPHER_CTX_cleanup (& ctx);
return true;
}


Ok, now let's see the other side of the story, from C++ to Java

Encryption in C++

Again Openssl provides a set of library functions for encryption as well. Following is the utility function for the encryption

bool

SecurityUtil::encryptAES(const unsigned char* in,int
inputLength ,unsigned char *out,int &outputLength, string
aesKey){

int olen, tlen, n;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (& ctx);

EVP_EncryptInit (& ctx, EVP_aes_128_ecb (), (unsigned char
*)aesKey.c_str(), NULL);

if (EVP_EncryptUpdate (& ctx, out, & olen, (const unsigned
char*)in , inputLength) != 1)
{
cerr<<"error in decrypt update"<

if (EVP_EncryptFinal (& ctx, out + olen, &amp;amp;amp;amp;amp;amp; tlen) != 1)
{
cerr<<"error in encrypt final"<

olen+=tlen;
outputLength=olen;

EVP_CIPHER_CTX_cleanup (& ctx);
return true;
}

Decrypting the bytes received from the C++ client in JAVA

Decryption is java is also handled by the javax.crypto.Cipher class and is fairly straight forward. Here is the code segment.

byte[] decBytes = null;

Cipher aesCipher;

try {
aesCipher = Cipher.getInstance(Constants.RSA_ALGO);

aesCipher.init(Cipher.DECRYPT_MODE, prKey);
decBytes = aesCipher.doFinal(msgBytes);

} catch (Exception e) {
throw new ClarensException(
"Error decrypting message using private key ", e);
}

Simple right? The main problem I faced when developing the above application was the lack of documentation on this regard. There are tons of documentation on how to handle encryption/decryption using java but very small number for the same in C++. How about encryption/decryption between Java and C++? I could not find anything in this sort. Openssl has a good documentation on various functions/data structures it offers for encryption/decryption but the main problem is there very limited amount of code examples which shows the exact usage. Followings are some of the resources that I used to come up with this implementation and hope someone will find this helpful.

http://www.openssl.org/docs/
http://www.madboa.com/geek/openssl/#cert-self
http://www.ibm.com/developerworks/linux/library/l-openssl.html
http://www.mail-archive.com/openssl-users@openssl.org/msg40449.html
http://www.mail-archive.com/openssl-users@openssl.org/msg23119.html
http://www.fortrel.net/blog/index.php?title=encryption_java_c&more=1&amp;c=1&tb=1&pb=1
http://www.adp-gmbh.ch/cpp/common/base64.html

Next Blog: Signing and Verifying between Java and C++

2 comments:

Kevin said...

Hello Jaliya,
I am trying to do exactly what you are posting about here. We are generating a key on the Java side, encrypting a message, sending the message, and decrypting the message on the c++ side using the same key, (or using a key pair as in RSA).

What we have had problems with is sharing the same key on both sides. Could you please include the code that shows the generation of the key on the java side and the re-creation of this key on the c++ side. I cannot seem to get c++ to use an already existing key.

Jaliya Ekanayake said...

Hi Kevin,

You can find the necessary code in from the following zip flie.

http://www.cs.indiana.edu/~jekanaya/security.zip

Good Luck!

Jaliya