Saturday 7 January 2012

Small crypto code for Android

I'd like to share a simple class that I wrote a while ago as a cryptographic utility for Android. It uses the Bouncy Castle crypto lib for JDK 6 and the Apache Base 64 encoder.

package org.oogifu.crypto;

import org.apache.base64.Base64;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;

public final class BCEncryptionUtils {
  private static final BCEncryptionUtils instance = new BCEncryptionUtils();
 
  private transient byte rawKey[] = null;
 
  private BCEncryptionUtils() {
  }
 
  public static BCEncryptionUtils getInstance() {
    return instance;
  }
 
  public String getCipherInfo() {
    return "AES-256 provided By Bouncy Castle";
  }

  public String getFormat() {
    return "256";
  }
 
  public void setMasterPassword(String password) throws Exception {
    final byte[] masterPassword = new byte[32];
    Arrays.fill(masterPassword, (byte)0);
     
    if (password.length() > 32) password = password.substring(0, 32);
       
    final byte[] source = password.getBytes();
       
    System.arraycopy(source, 0, masterPassword, 0, source.length);
       
    rawKey = masterPassword;
  }

  public String decryptFromBase64(final String edata64) throws Exception {
    final byte[] edb = Base64.decodeBase64(edata64);
    final byte[] data = decode(edb);
    return new String(data).trim();
  }

  public String encryptToBase64(final String data) throws Exception {
    final byte[] newData = data.getBytes("UTF-8");
    return Base64.encodeBase64String(encode(newData));
  }
 
  private byte[] encode(final byte[] inputBytes) throws Exception {
    final BufferedBlockCipher cipher = getCipher(true);
    final byte[] outputBytes = new byte[cipher.getOutputSize(inputBytes.length)];
  
    int outputLen = cipher.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0);
    outputLen += cipher.doFinal(outputBytes, outputLen);
     
    return outputBytes;
  }
 
  private byte[] decode(final byte[] inputBytes) throws Exception {
    final BufferedBlockCipher cipher = getCipher(false);
  
    final byte[] outputBytes = new byte[cipher.getOutputSize(inputBytes.length)];
   
    int outputLen = cipher.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0);
    outputLen += cipher.doFinal(outputBytes, outputLen);
     
    return outputBytes;
  }
 
  private BufferedBlockCipher getCipher(final boolean forEncryption) {
    final BlockCipher aesEngine = new AESFastEngine();
    final BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(aesEngine, new PKCS7Padding());
    cipher.init(forEncryption, new KeyParameter(rawKey));
    return cipher;
  }
}


No comments:

Blog Archive