Encryption/Decryption Layer for JavaGroups

Chung-A Choi

 460113

Chunga@cs.cornell.edu

Shen-Ban Meng

460121

Shenban@cs.cornell.edu

 

Purpose

JavaGroups is a convenient toolkit for group communication. The protocol stack architecture of JavaGroups is easy for programmers to implement new independent protocols without changing the original ones.

But in-group communications, it’s easier to eavesdrop messages than point to point communication. We hope to implement an encryption/decryption protocol which can be put into the protocol stack and provide security features to the JavaGroups.

Background

The goal of computer security is to institute controls that preserve confidentiality, integrity, and availability. The most powerful tool in providing computer security is coding. Encryption provides confidentiality for data. Additionally, encryption can be used to achieve integrity because data that cannot be read generally also cannot be changed in a meaningful manner. For security reason, when they send the important data to other members in JavaGroups, they can encrypt and decrypt message.

There are two kinds of encryption/decryption.

With asymmetric encryption system, each user has two keys: a public key and a private key. One for encryption and another for decryption, so that one key can be made available to anyone wishing to send encrypted information, and the other key –which is kept secret- is the only key that can decrypt that information The keys operate as inverses.

Let kpriv be a user’s private key, and let Kpub be the corresponding public key. D is the decrypt function and E is the encrypt function. Then,

P = D(kpriv,E(Kpub,P))

P = E(Kpub,D(kpriv,P))
That is, a user can decode with a private key what someone else has encrypted with the corresponding public key, or reverse.

With public keys, only two keys are needed per user: one public and one private. B, C, and D can all encrypt messages for A using A’s public key. If B has encrypted a message using A’s public key, C cannot decrypt it, even if C knew it was encrypted with A’s public key.

- Merkle-Hellman Knapsakcs

- RSA (Rivest-Shamir-Adelman) Encryption

 

The algorithms were all single key or conventional encryption algorithms, in which both the encryptor and the decryptor use the same key, which must be kept secret.

- Advantages: As long as the key remains secret, the systems also provides authentication, proof that a message received was not fabricated by someone other than the declared sender.

- Problems:

    1. With all key systems, if the key is revealed, the interceptors can immediately decrypt all encrypted information they have available. Furthermore, an impostor using an intercepted key can produce bogus messages under the guise of a legitimate sender. For this reason, in secure encryption systems, the keys are changed fairly frequently so that a compromised key will reveal only a limited amount of information.
    2. Distribution of Keys becomes a problem. Keys must be transmitted with utmost security because they allow access to all information encrypted under them.
    3. The symmetric key encryption systems have been relatively weak, vulnerable to various cryptanalytic attacks.

- DES (Data Encryption Standard)

Our Design

Typically, asymmetric key encryption algorithms are significantly slower than symmetric ones, often by several orders of magnitude. Thus, while encryption itself burdens communication speed, asymmetric key encryption burdens it to a degree that is often unacceptable. For this reason, JavaGouprs may not want to use a public key algorithm to protect their entire communication.

The other reason to choose symmetric key for encryption and decryption the information is if we choose the asymmetric key and there are 5 member in a groups, each member should have his own private key to decrypt and 4 other’s public key to encrypt the message. It wastes a lot of memory usage and time. When one member send a message, it has to encrypt that message 4 times with different public keys.

But if we use the symmetric key for encryption and decryption, the problem is key distribution. As mentioned before, if symmetric key is revealed, it causes to big problem. And another problem is key distribution.

Therefore, we use the symmetric key for encryption and decryption message and asymmetric key systems is used for encrypt and decrypt the shared key for key distribution. For key distribution in an asymmetric key, there are key server and clients. Key server randomly generates the shared key when it is created.

Phase 1: New member joins the group

When a client want to join the group, client sends its public key to the key server and requests the shared key. When the key server get this request from client, server sends its public key and the shared key encrypted using client’s public key and its own private key. This algorithm reduces the server’s key management efforts. When client request the shared key, it first sends its public key; the server gets client’s public key, and encrypt using that public key, and never store it in memory. This reduces a lot the amount of memory space needed, and if there are a lot of members in the same group, this algorithm is very helpful.

Phase 2: Encryption and Decryption the message

Using a shared key, members in a one group can exchange their message without worrying about what kind of key other member gets.

Phase 3: Member leaves the group

If a member leaves the group, the group needs a new shared key. Because, old member’s shared key can be revealed by other people. Whenever a member leaves the group, key server computes a new shared key and other clients request the new shared key from key server. After this, same as phase 1.

 

Installation

1. The encryption/decryption layer should run on the JDK1.2

2. Install the JCE1.2 and ABA JCE1.1 (if user wants to use RSA algorithm for asymmetric algorithm)

JCE1.2 can be found at http://www.javasoft.com/products/jce/

ABA JCE1.1 can be found at http://www.aba.net.au/solutions/crypto/jce.html

3. If you want to use other API provider for encrypt algorithm, change the following line in the code.

Security.addProvider(new ABAProvider());

 

Usage

1. If user wants to include the encryption/decryption layer, place the encryption layer below the GMS layer.

2. Properties

asymAlgorithm : set the asymmetric algorithm for shared key distribution
Default : "RSA" is used for asymmetric algorithm

symAlrithm : set the symmetric algorithm for encrypting and decrypting message
The format of symmetric algorithm is: "algorithm/mode/padding". For example, "DES/CBC/PKCS5Padding"
Default : "DES/ECB/PKCS5Padding"

asymInit : set the key length(strength) for asymmetric algorithm
Default: 512 bits

symInit : set the key length(strength) for symmetric algorithm
Default: 56 bits

 

Implementation

The Encryption/Decryption layer is in charge of encrypting and decrypting the messages in a group. We decided to implement shared key algorithm in Encryption/Decryption layer. It would be simpler and more appropriate for an independent layer. When a new member joins, the old member will pass the shared key to the new one. And for safety, when an old member leaves, the group will pick another shared key and distribute it to whole members.

  1. RSA algorithm for asymmetric algorithm
  2. Basic conception of RSA:

    RSA uses the public-private-key system to exchange shared keys.

     

    A and B both know each other’s public key. A produces the shared key, and sends out the shared key that is decrypted with A’s private key and then encrypted with B’s public key. B can get the shared key by decrypting the message with B’s private key and then encrypting with A’s public key.

    A class that provides RSA public/private key encryption and decryption as specified in PKCS#1.

    By default this cipher will use PKCS#1 padding however it also supports NoPadding.

     

  3. DES algorithm for symmetric algorithm

This class supports PKCS#5 and NoPadding, as well as supporting ECB and CBC modes. The standard block size is 8.

To implement a new block cipher it is necessary to implement the three abstract methods that re-key the cipher, do encryption and decryption using the current. It may also be necessary to override the engineSetMode method if CBC or ECB are not supported. If different padding mechanisms are used engineSetPadding may be overridden (in which case it may also be necessary to override engineGetOutputSize). For block sizes other than 8 engineGetBlockSize should be overridden. Finally if the algorithm supports AlgorithmParameterSpec just override the engineInit method that accepts those parameters.

 

 

Our Algorithm

We pick the coordinator as a key distribution server. Key distribution server is in charge of distributing the shared key to every member.

Initialization

Each member will initialize a DES shared key and a pair of RSA public and private keys when it is invoked.

Create shared key:

KeyGenerator keyGen = KeyGenerator.getInstance("DES");
keyGen.init(56);
SecretKey desKey = keyGen.generateKey();

Create public and private key pair:

KeyPairGenerator KpairGen = KeyPairGenerator.getInstance("RSA");
KpairGen.initialize(512, new SecureRandom());
KeyPair Kpair = KpairGen.generateKeyPair();

But when a member finds out that it is not the key server (coordinator), it will flush its shared key.

Phase 1: New member joins

Each time a new member joins, the new member will pass its public key with KEY_REQUEST header. Key server then returns its public key with SERVER_PUBKEY header, followed by the encrypted shared key with SECRETKEY header. After the member gets the secret key, it sends a message with SECRETKEY_READY header to server to announce that it’s ready for encryption.

But there’re many other messages transferred between members when a new member joins the group before the new member is ready for encryption. So the key server keeps a record of those who are not ready for encryption. If a message is going to a member who is not ready yet, the key server will send the message out without encryption. So the new member could join the group successfully and get the shared key correctly. After the member gets the shared key and sends a message with SECRETKEY_READY header to server, server will delete it from the not-ready list and send messages encrypted to the member.

Key server:

rsa = Cipher.getInstance("RSA");

//decrypt secretKey using server’s private key

rsa.init(Cipher.ENCRYPT_MODE, Kpair.getPrivate());byte [] decryptedKey = rsa.doFinal(desKey.getEncoded());

// encrypt decrypted key using client's public key

rsa.init(Cipher.ENCRYPT_MODE, pubKey);byte [] encryptedKey = rsa.doFinal(decryptedKey);

//send encrypted deskey to clientnewMsg = new Message(msg.GetSrc(), local_addr, encryptedKey);newMsg.AddHeader(new EncryptHeader(EncryptHeader.SECRETKEY));PassDown(new Event(Event.MSG, newMsg));

 

Client:

rsa = Cipher.getInstance("RSA");

rsa.init(Cipher.DECRYPT_MODE,Kpair.getPrivate());byte[] decryptedKey = rsa.doFinal(msg.GetBuffer());

// decrypt using server's public Keyrsa.init(Cipher.DECRYPT_MODE,serverPubKey);byte[] encodedKey = rsa.doFinal(decryptedKey);

// decode secretKeydesKey = decodedKey(encodedKey);System.out.println("Client generate shared secret key");

// send ready messagenewMsg = new Message(msg.GetSrc(), local_addr,null);newMsg.AddHeader(new EncryptHeader(EncryptHeader.SECRETKEY_READY));PassDown(new Event(Event.MSG, newMsg));

Phase 2: Encryption and decryption

After a member gets the shared key, it will start to encrypt messages before sending and decrypt messages after receiving. Here are some sample codes of how to encrypt and decrypt with DES shared key.

Encrypt:

In method Down, ENCRYPT protocol encrypts outgoing messages like following:

Cipher cipher;
cipher.init(Cipher.ENCRYPT_MODE, desKey);
byte [] encrypted = cipher.doFinal(plaintext);

Decrypt:

In method Up, ENCRYPT protocol decrypts incoming messages like following:

Cipher cipher;
cipher.init(Cipher.DECRYPT_MODE, desKey);
byte [] plaintext = cipher.doFinal(encrypted);

Phase 3: Member leaves the group

If an old member leaves, the group should pick a new shared key for safety. Whenever the key server detects an old member leaving, it computes a new shared key and broadcasts it with NEWKEY header encrypted with the old key. Other members will decrypt the new key and set the new key as their shared key.

But if the key server leaves, the new coordinator will become the new key server, and all the work will be done by the new key server.

Key Server : generate the new shared key

// reset shared key

desKey=null;

//generate new shared key

KeyGenerator keyGen = KeyGenerator.getInstance("DES");

keyGen.init(symInit);

desKey = keyGen.generateKey();

Client : send client’s public key and request new shared key

// reset shared key desKey = null;

// client send clien's public key to server and request server's public key

newMsg = new Message(keyServerAddr, local_addr, Kpair.getPublic().getEncoded());

newMsg.AddHeader(new EncryptHeader(EncryptHeader.KEY_REQUEST)); PassDown(new Event(Event.MSG, newMsg));

 

Known Problems

1. If a member joins the group and doesn’t process the key distribution, it will remain on server’s not-ready list and get server’s messages unencrypted.

2. Better to use timeout and re-send mechanism to prevent data lost during key exchange.

Reference

Bela Ban "Design and Implementation of a Reliable Group Communication Toolkit for Java" http://www.cs.cornell.edu/home/bba/Coots.ps.gz

Bela Ban "JavaGroups User's Guide" http://www.cs.cornell.edu/home/bba/user/index.html

Sun Microsystems. "API Specification & Reference of JCE1.2" http://java.sun.com/security/JCE1.2/spec/apidoc/index.html

Australia Business Access. "API Documentation of ABA-JCE1.1" http://www.aba.net.au/solutions/crypto/jce.html