/**
* Copyright (C) 2011 Adriano Monteiro Marques
*
* Author: Zubair Nabi <zn.zubairnabi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
package org.umit.icm.mobile.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.umit.icm.mobile.process.Constants;
import android.os.Environment;
/**
* Provides methods for AES symmetric cryptography
*/
public class AESCrypto {
/**
* Returns an encrypted {@link String} of the Plain text passed.
* Calls {@link AESCrypto#encrypt(byte[], byte[])}. Uses
* {@link CryptoHelper#toHex(byte[])}.
*
@param plainText An object of the type {@link String}
*
@param key An object of the type {@link String}
*
@return {@link String}
*
@see CryptoHelper
*/
public static String encrypt(String key, String plainText) throws Exception {
byte[] generatedKey = generateKey(key.getBytes());
byte[] cipherText = encrypt(generatedKey, plainText.getBytes());
return CryptoHelper.toHex(cipherText);
}
/**
* Returns an decrypted {@link String} of the cipher text passed.
* Calls {@link AESCrypto#decrypt(byte[], byte[])}. Uses
* {@link CryptoHelper#toByte(String)}.
*
@param cipherText An object of the type {@link String}
*
@param key An object of the type {@link String}
*
@return {@link String}
*
@see CryptoHelper
*/
public static String decrypt(String key, String cipherText) throws Exception {
byte[] generatedKey = generateKey(key.getBytes());
return new String(decrypt(generatedKey, CryptoHelper.toByte(cipherText)));
}
/**
* Returns an AES secret key using the passed byte[] as seed.
* *
@param key An object of the type byte[]
*
@return byte[]
*
@see SecureRandom
*
@see KeyGenerator
*/
public static byte[] generateKey(byte[] key) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
randomGen.setSeed(key);
keyGen.init(Constants.AES_KEY_SIZE, randomGen);
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
}
/**
* Returns an encrypted byte[] of the Plain bytes passed.
* Encrypts using {@link Cipher}.
*
*
@param plainBytes An object of the type byte[]
*
@param byteKey An object of the type byte[]
*
@return byte[]
*
@see Cipher
*/
public static byte[] encrypt(byte[] byteKey, byte[] plainBytes) throws Exception {
SecretKeySpec secretkeySpec = new SecretKeySpec(byteKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretkeySpec);
return cipher.doFinal(plainBytes);
}
/**
* Returns an decrypted byte[] of the cipher bytes passed.
* Uses {@link Cipher}.
*
@param cipherBytes An object of the type byte[]
*
@param byteKey An object of the type byte[]
*
@return byte[]
*
@see Cipher
*/
public static byte[] decrypt(byte[] byteKey, byte[] cipherBytes) throws Exception {
SecretKeySpec secretkeySpec = new SecretKeySpec(byteKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, secretkeySpec);
return cipher.doFinal(cipherBytes);
}
/**
* Writes an AES key to disk.
*
@param fileName An object of the type {@link String}
*
@param secretKey An object of the type byte[]
*
@see SDCardReadWrite
*/
public static void saveKey(String fileName, byte[] secretKey)
throws IOException{
ObjectOutputStream objOutStream = null;
File sdCard = Environment.getExternalStorageDirectory();
File keyDir = new File (sdCard.getAbsolutePath()
+ Constants.KEYS_DIR);
keyDir.mkdirs();
File file = new File(keyDir, fileName);
try {
objOutStream = new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream(file)));
objOutStream.writeObject(secretKey);
} catch (Exception e) {
throw new RuntimeException("AES writeKey exception", e);
} finally {
objOutStream.close();
}
}
/**
* Reads an AES key from disk.
*
@param fileName An object of the type {@link String}
*
@return byte[]
*
@see SDCardReadWrite
*/
public static byte[] readKey(String fileName) throws IOException{
File sdCard = Environment.getExternalStorageDirectory();
File keyDir = new File (sdCard.getAbsolutePath()
+ Constants.KEYS_DIR);
File file = new File(keyDir, fileName);
InputStream inputStream = new FileInputStream(file.toString());
ObjectInputStream objInputStream =
new ObjectInputStream(new BufferedInputStream(inputStream));
try {
return (byte[]) objInputStream.readObject();
} catch (Exception e) {
throw new RuntimeException("AES readKey exception", e);
} finally {
objInputStream.close();
}
}
}