February 17, 2010

Java Bouncycastle DES CBC

Here is the sample code to encrypt/ decrypt with DES CBC algorithm using bouncycastle library

import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.*;

/**
*
* @author http://myprogramminglab.blogspot.com
*/
public class Main {

    public static void main(String[] args) {
        //add the security provider
        //not required if you have Install the library
        //by Configuring the Java Runtime
        Security.addProvider(new BouncyCastleProvider());

        //DES only accept encryption key with
        //8 bytes length only
        byte[] EncryptionKey = {0x01, 0x12, 0x23, 0x34,
            0x45, 0x56, 0x67, 0x78};

        //DES without padding must contains data length n * 8
        byte[] input = {0x01, 0x02, 0x03, 0x04, 0x05,
            0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
            0x16, 0x17, 0x18};

        byte[] iv = new byte[] {0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00};

        //show the input to the screen
        System.out.println("Input: " +
            new String(Hex.encode(input)));

        SecretKeySpec key = new SecretKeySpec(
                EncryptionKey, "DES");

        try
        {
            //set the iv psec
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            //get the cipher instance
            Cipher cipher = Cipher.getInstance(
                    "DES/CBC/NoPadding", "BC");

            //init the cipher
            cipher.init(Cipher.ENCRYPT_MODE,
                    key, ivSpec);

            //get the output length
            byte[] cipherText = new byte[
                    cipher.getOutputSize(input.length)];

            int ctLength = cipher.update(input, 0,
                    input.length, cipherText, 0);
            ctLength += cipher.doFinal(cipherText, ctLength);

            //show the encrypted text to the screen
            System.out.println("Encrypted Input: " +
                    new String(Hex.encode(cipherText)));

            //decrypt it back
            cipher.init(Cipher.DECRYPT_MODE,
                    key, ivSpec);

            //get the output text (decrypted text
            byte[] decryptedText = new byte[
                    cipher.getOutputSize(input.length)];

            ctLength = cipher.update(cipherText, 0,
                    cipherText.length, decryptedText, 0);
            ctLength += cipher.doFinal(decryptedText,
                    ctLength);

            //show the decrypted text to the screen
            System.out.println("Decrypted Input: " +
                    new String(Hex.encode(decryptedText)));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


You will see this output:
Input: 01020304050607081112131415161718
Encrypted Input: 96288ada0931eea3180d8d9c79885be1
Decrypted Input: 01020304050607081112131415161718

The sample code is very similar to Java Bouncycastle DES ECB. There are only few slight difference, so I'd just brief a bit about the differences.

byte[] iv = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
is to set the value of initialization vector of DES CBC. DES CBC would XOR the input block with the block of previous result (every block = 8 bytes). For the first block, the input will be XORed with the initialization vector. In this sample we set the initialization vector as "000 ... 00". So if we compare to the DES ECB result (refer to Java Bouncycastle DES ECB), the 1st block (8 bytes) is the same since we set the initialization vector as "00 ... 00"

IvParameterSpec ivSpec = new IvParameterSpec(iv);
is to setup the initialization vector

The last difference is that we have to include the initialization vector (ivSpec) as the 3rd argument when we call the init() function
cipher.init(Cipher.ENCRYPT_MODE,key, ivSpec);

1 comment: