Thursday, December 13, 2012

AES Encryption Bouncy Castle Example

Here's a little example, showing how to perform AES encryption in CTR mode using Bouncy Castle. My example is in Scala, but the idea is the same for Java. I've placed all of the code on Git: https://github.com/travisdazell/AES-CTR-BOUNCYCASTLE

To start with, here's an "encrypt" method that takes a key, IV (initialization vector), and message and returns the encryption of the message under the specified key and IV. All of the method parameters are expected to be hex-encoded. Note that I'm using a utility method I created to convert the hex strings to byte arrays, which is what the crypto library expects as input. This utility method is included in the code on Git.

def encrypt(hexEncodedIv : String, hexEncodedKey : String, hexEncodedMessage : String) = {
    // we're using Bouncy Castle
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())

    // create our key specification
    val secretKeySpec = new SecretKeySpec(hexStringToByteArray(hexEncodedKey), "AES")
     
    // create an AES engine in CTR mode (no padding)
    val aes = Cipher.getInstance("AES/CTR/NoPadding", BouncyCastleProvider.PROVIDER_NAME)
     
    // initialize the AES engine in encrypt mode with the key and IV
    aes.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(hexStringToByteArray(hexEncodedIv)))
     
    // encrypt the message and return the encrypted byte array
    aes.doFinal(hexStringToByteArray(hexEncodedMessage))
}


Our "decrypt" method will be the same as the "encrypt" method; however, instead of Cipher.ENCRYPT_MODE, we'll use Cipher.DECRYPT_MODE. Of course, we'll be passing the ciphertext to the method instead of the plaintext message.

def decrypt(hexEncodedIv : String, hexEncodedKey : String, hexEncodedCipherText : String) = {
    // we're using Bouncy Castle
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())

    // create our key specification
    val secretKeySpec = new SecretKeySpec(hexStringToByteArray(hexEncodedKey), "AES")
     
    // create an AES engine in CTR mode (no padding)
    val aes = Cipher.getInstance("AES/CTR/NoPadding", BouncyCastleProvider.PROVIDER_NAME)
     
    // initialize the AES engine in decrypt mode with the key and IV
    aes.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(hexStringToByteArray(hexEncodedIv)))
     
    // decrypt the ciphertext and return the plaintext as a byte array
    aes.doFinal(hexStringToByteArray(hexEncodedCipherText))
}