/* *******************************************
* Copyright (c) 2011
* HT srl, All rights reserved.
* Project : RCS, AndroidService
* File : Crypto.java
* Created : Apr 9, 2011
* Author : zeno
* *******************************************/
package com.android.dvci.crypto;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.android.dvci.action.sync.Statistics;
import com.android.dvci.auto.Cfg;
import com.android.mm.M;
// TODO: Auto-generated Javadoc
/**
* http://www.androidsnippets.org/snippets/39/index.html
*
* @author zeno
*
*/
public class Crypto {
/** The Constant TAG. */
private static final String TAG = "Crypto"; //$NON-NLS-1$
/** The aes_key. */
private final byte[] aes_key;
/** The skey_spec. */
private final SecretKeySpec skey_spec;
/** The iv spec. */
private final IvParameterSpec ivSpec;
/** The cipher. */
Cipher cipherEnc;
Cipher cipherDec;
/**
* Instantiates a new crypto.
*
* @param key
* the key
* @throws NoSuchAlgorithmException
* the no such algorithm exception
* @throws NoSuchPaddingException
* the no such padding exception
* @throws InvalidAlgorithmParameterException
* @throws InvalidKeyException
*/
public Crypto(final byte[] key, boolean encrypt) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException {
this(key);
// 17.1=AES/CBC/NoPadding
if (encrypt) {
cipherEnc = Cipher.getInstance(M.e("AES/CBC/NoPadding")); //$NON-NLS-1$
cipherEnc.init(Cipher.ENCRYPT_MODE, skey_spec, ivSpec);
} else {
cipherDec = Cipher.getInstance(M.e("AES/CBC/NoPadding")); //$NON-NLS-1$
cipherDec.init(Cipher.DECRYPT_MODE, skey_spec, ivSpec);
}
}
public Crypto(final byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException {
aes_key = new byte[key.length];
System.arraycopy(key, 0, aes_key, 0, key.length);
// 17.0=AES
skey_spec = new SecretKeySpec(aes_key, "AES"); //$NON-NLS-1$
final byte[] iv = new byte[16];
for (int i = 0; i < 16; i++) {
iv[i] = 0;
}
ivSpec = new IvParameterSpec(iv);
cipherEnc = Cipher.getInstance("AES/CBC/NoPadding"); //$NON-NLS-1$
cipherEnc.init(Cipher.ENCRYPT_MODE, skey_spec, ivSpec);
cipherDec = Cipher.getInstance("AES/CBC/NoPadding"); //$NON-NLS-1$
cipherDec.init(Cipher.DECRYPT_MODE, skey_spec, ivSpec);
}
/**
* Encrypt.
*
* @param clear
* the clear
* @return the byte[]
* @throws Exception
* the exception
*/
public byte[] encrypt(final byte[] plain) throws Exception {
Statistics statistics;
if (Cfg.STATISTICS) {
statistics = new Statistics("encrypt");
statistics.start(false);
statistics.addIn(plain.length);
}
final byte[] encrypted = cipherEnc.doFinal(plain);
if (Cfg.STATISTICS) {
statistics.stop();
}
return encrypted;
}
public byte[] encrypt(byte[] plain, int offset) throws IllegalBlockSizeException, BadPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException {
Statistics statistics;
if (Cfg.STATISTICS) {
statistics = new Statistics("encrypt");
statistics.start(false);
statistics.addIn(plain.length);
}
final byte[] encrypted = cipherEnc.doFinal(plain, offset, plain.length - offset);
if (Cfg.STATISTICS) {
statistics.stop();
}
return encrypted;
}
public byte[] encrypt(byte[] plain, int offset, byte[] iv) throws IllegalBlockSizeException, BadPaddingException {
IvParameterSpec ivSpecIter = new IvParameterSpec(iv);
try {
cipherEnc.init(Cipher.ENCRYPT_MODE, skey_spec, ivSpecIter);
} catch (InvalidKeyException e) {
return null;
} catch (InvalidAlgorithmParameterException e) {
return null;
}
Statistics statistics;
if (Cfg.STATISTICS) {
statistics = new Statistics("encrypt");
statistics.start(false);
statistics.addIn(plain.length);
}
final byte[] encrypted = cipherEnc.doFinal(plain, offset, plain.length);
if (Cfg.STATISTICS) {
statistics.stop();
}
return encrypted;
}
/**
* Decrypt.
*
* @param encrypted
* the encrypted
* @return the byte[]
* @throws Exception
* the exception
*/
public byte[] decrypt(final byte[] encrypted) throws Exception {
// final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
Statistics statistics;
if (Cfg.STATISTICS) {
statistics = new Statistics("decrypt");
statistics.start(false);
statistics.addIn(encrypted.length);
}
final byte[] decrypted = cipherDec.doFinal(encrypted);
if (Cfg.STATISTICS) {
statistics.stop();
}
return decrypted;
}
/**
* Decrypt.
*
* @param encrypted
* the encrypted
* @param offset
* the offset
* @param offset2
* @return the byte[]
* @throws Exception
* the exception
*/
public byte[] decrypt(final byte[] encrypted, final int plainlen, int offset) throws Exception {
if (offset < 0 || encrypted.length < offset) {
return null;
}
Statistics statistics;
if (Cfg.STATISTICS) {
statistics = new Statistics("decrypt");
statistics.start(false);
statistics.addIn(encrypted.length);
}
byte[] plain = cipherDec.doFinal(encrypted, offset, encrypted.length - offset);
if (Cfg.STATISTICS) {
statistics.stop();
}
byte[] dst = new byte[plainlen];
System.arraycopy(plain, 0, dst, 0, plainlen);
return dst;
}
}