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);

February 2, 2010

Java Bouncycastle DES ECB

How to send a message securely? One of the option is to use symmetric cipher.
DES is one of the most popular symmetric cipher. It is old but some applications still use this algorithm.
And off course bouncycastle also provides the library for DES. Here is the code for the most basic DES, ECB DES:


import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
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};


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

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

        try
        {

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

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

            //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);

            //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: 96288ada0931eea3f605e383b0ad3510
Decrypted Input: 01020304050607081112131415161718

Let us discuss the code:

SecretKeySpec key = new SecretKeySpec(EncryptionKey, "DES");
is to initialize the key for encrypting/ decrypting the input

Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding", "BC");
is to get the cipher instance. We use DES ECB algorithm without padding. If we choose for not including padding then the length of input must be (n * 8), where n is an integer that is larger than 0. If it is not (n * 8) then we'll get an IllegalBlockSizeException. You can add a padding from the code by yourself or you can use the padding modes that are provided by bouncycastle, such as PKCS5Padding, PKCS7Padding, ISO10126-2Padding, ISO7816-4Padding, X9.23Padding, TBCPadding, or ZeroBytePadding.

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

Those lines are for encrypting or decrypting the input and put it to the output. The return value that is passed to ctLength is to get the real length of output, it might be lesser than the cipher.getOutputSize(). Before you proceed the encryption/ decryption process. You have to call the cipher.init() to choose the mode. In the code we choose to encrypt the input, the encrypted value is stored in cipherText variable and later we decrypt it again and store the decrypted value to decryptedText variable. The result shows that input and decryptedText is the same.

January 16, 2010

Java Bouncycastle SHA-1

Again, let’s try the next message digest algorithm SHA-1 using the bouncycastle library.
Recently, SHA-1 is quite popular in the CDMA industries since the algorithm is being used for generating the pseudo ESN/ pseudo UIMID.
And here is the code:


import java.security.Security;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.*;
import java.security.MessageDigest;

/**
*
* @author http://myprogramminglab.blogspot.com/
*/
public class sha1hash {
   public static void main(String[] args) {
       Security.addProvider(new BouncyCastleProvider());

      //this is the input;
      byte input[] = {0x30, 0x31, 0x32, 0x33, 0x34};

      try
      {
            //prepare the input
            MessageDigest hash =
               MessageDigest.getInstance("SHA-1", "BC");
            hash.update(input);

            //proceed ....
            byte[] digest = hash.digest();

            //show us the result
            System.out.println("input: " +
                   new String(Hex.encode(input)));
            System.out.println("result: " +
                   new String(Hex.encode(digest)));
      }
      catch (NoSuchAlgorithmException e)
      {
            System.err.println("No such algorithm");
            e.printStackTrace();
      }
      catch (NoSuchProviderException e)
      {
            System.err.println("No such provider");
            e.printStackTrace();
      }
   }
}


You will see this output:
input: 3031323334
result: 11904a4e8b77f6242e2d288705023adad00a9310

Let us discuss the code:

Security.addProvider(new BouncyCastleProvider());
is to install the bouncycastle provider during execution. You can also install it by configuring the Java Runtime which we won’t discuss in this topic

MessageDigest hash = MessageDigest.getInstance("SHA-1", "BC");
hash.update(input);

is to prepare the construct the MessageDigest class by calling getInstance. The first argument is the MessageDigest algorithm and the second argument is the provider. If you use bouncycastle library, then the provider is "BC" and since we use SHA-1 algorithm, the first argument is "SHA-1". The next line is to setup the input of the MessageDigest.

byte[] digest = hash.digest();
As you probably have guest, the digest function will digest the input and return the result.

System.out.println("input: " +
   new String(Hex.encode(input)));
System.out.println("result: " +
   new String(Hex.encode(digest)));

And the final step is to show the input and output to the screen.

January 10, 2010

Java Bouncycastle MD5

MD5 is one of a well known message digest/ hash algorithm. There are many websites where you can download free MD5 software but if you would like to build your own customize application, you can use Java open source library: bouncycastle.

Here is one of simple code that demonstrates how to utilize the bouncycastle library for MD5 algorithm.

import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.*;
import org.bouncycastle.crypto.digests.*;

/**
* @author http://myprogramminglab.blogspot.com/
*/

public class md5hash {
    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());

        //this is the input;
        byte input[] = {0x00, 0x01, 0x02, 0x03, 0x04};

        //update the input of MD5
        MD5Digest md5 = new MD5Digest();
        md5.update(input, 0, input.length);

        //get the output/ digest size and hash it
        byte[] digest = new byte[md5.getDigestSize()];
        md5.doFinal(digest, 0);

        //show the input and output
        System.out.println("Input (hex): " +
            new String(Hex.encode(input)));
        System.out.println("Output (hex): " +
            new String(Hex.encode(digest)));
    }
}

You will see this output:
Input (hex): 0001020304
Output (hex): d05374dc381d9b52806446a71c8e79b1

To focus on the MD5 function of bouncycastle library, the input is set to fix value.