Showing posts with label Symmetric. Show all posts
Showing posts with label Symmetric. Show all posts

Sunday, 19 August 2012

AES 256 Symmetric Encryption with BouncyCastle

Java provides the Cipher class to perform symmetric encryption. Several algorithms are available, but unfortunately, not all key sizes are allowed. The recommended solution is to install the unlimited JCE version. However, this is not a portable solution.

Trying to perform AES encryption with a 256 bit key triggers an error. A portable solution is to use BouncyCastle's library instead:
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk16</artifactId>
    <version>1.46</version>
</dependency>
The following class illustrates how BounceCastle can be used for AES:
public class AESBouncyCastle {

    private final BlockCipher AESCipher = new AESEngine();

    private PaddedBufferedBlockCipher pbbc;
    private KeyParameter key;

    public void setPadding(BlockCipherPadding bcp) {
        this.pbbc = new PaddedBufferedBlockCipher(AESCipher, bcp);
    }

    public void setKey(byte[] key) {
        this.key = new KeyParameter(key);
    }

    public byte[] encrypt(byte[] input)
            throws DataLengthException, InvalidCipherTextException {
        return processing(input, true);
    }

    public byte[] decrypt(byte[] input)
            throws DataLengthException, InvalidCipherTextException {
        return processing(input, false);
    }

    private byte[] processing(byte[] input, boolean encrypt)
            throws DataLengthException, InvalidCipherTextException {

        pbbc.init(encrypt, key);

        byte[] output = new byte[pbbc.getOutputSize(input.length)];
        int bytesWrittenOut = pbbc.processBytes(
            input, 0, input.length, output, 0);

        pbbc.doFinal(output, bytesWrittenOut);

        return output;

    }

}
It can be used as following:
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256);
SecretKey sk = kg.generateKey();

AESBouncyCastle abc = new AESBouncyCastle();
abc.setPadding(new PKCS7Padding());
abc.setKey(sk.getEncoded());

String secret = "This is a secret message!";
System.out.println(secret);
byte[] ba = secret.getBytes("UTF-8");

byte[] encr = abc.encrypt(ba);
System.out.println("Encrypted : "
    + Hex.encodeHexString(encr));
byte[] retr = abc.decrypt(encr);

if ( retr.length == ba.length ) {
    ba = retr;
} else {
    System.arraycopy(retr, 0, ba, 0, ba.length);
}

String decrypted = new String(ba, "UTF-8");
System.out.println(decrypted);
The above starts by creating an AES 256 private key (more about private key generation here). Next, a padding is set. From the Javadoc, available paddings are: ISO10126d2, ISO7816d4, PKCS7, TBC, X923 and ZeroByte.

After retrieving the decrypted byte array, we check for its length, because AES operates with blocks of bytes. The original message length may not be a multiple of these block length.

The generated output is:
This is a secret message!
Encrypted : 6d204e3e52daee09800ba6fd9080653dad04a3d4725f3502b78a89b2150e1f63
This is a secret message!
The Hex class is an Apache Commons tool.

Saturday, 18 August 2012

AES 128-192-256 Private Key Generation in Java

Java delivers a standard tool called KeyGenerator to generate private keys. The following describes how to generate private (or symmetric) keys for AES (other algorithms are available too):
KeyGenerator kg = KeyGenerator.getInstance("AES");
SecretKey sk;

kg.init(128);
sk = kg.generateKey();
System.out.print("AES 128 - ");
System.out.println(Hex.encodeHex(sk.getEncoded()));

kg.init(192);
sk = kg.generateKey();
System.out.print("AES 192 - ");
System.out.println(Hex.encodeHex(sk.getEncoded()));

kg.init(256);
sk = kg.generateKey();
System.out.print("AES 256 - ");
System.out.println(Hex.encodeHex(sk.getEncoded()));
The generated output is:
AES 128 - 737677d940a988b04d99667406ea0d18
AES 192 - 727f44e3052aa4a6a72e385b9e9b421592f9ca1f5779925c
AES 256 - 383062669b33959fd8b57d93401c18c9d85d588ee90bb4ee82e486ac90620264
The Hex class is an Apache Commons tool.