@Override public String decrypt(ZWEncryptedData encryptedData) throws ZWKeyCrypterException { try { String encrypted = encryptedData.getEncryptedData(); Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM); int ivLength = decryptionCipher.getBlockSize(); String ivHex = encrypted.substring(0, ivLength * 2); String encryptedHex = encrypted.substring(ivLength * 2); IvParameterSpec ivspec = new IvParameterSpec(ZiftrUtils.hexStringToBytes(ivHex)); decryptionCipher.init(Cipher.DECRYPT_MODE, this.secretKey, ivspec); byte[] decryptedText = decryptionCipher.doFinal(ZiftrUtils.hexStringToBytes(encryptedHex)); String decrypted = new String(decryptedText, "UTF-8"); return decrypted; } catch (Exception e) { throw new ZWKeyCrypterException("Unable to decrypt", e); } }
private static byte[] generateIv(int ivLength) { SecureRandom random = ZiftrUtils.createTrulySecureRandom(); if (random == null) { String rngError = ZWApplication.getApplication().getString(R.string.zw_dialog_error_rng); ZiftrDialogManager.showSimpleAlert(rngError); } byte[] iv = new byte[ivLength]; random.nextBytes(iv); return iv; }
public static String generateSalt() throws ZWKeyCrypterException { try { SecureRandom random = ZiftrUtils.createTrulySecureRandom(); if (random == null) { String rngError = ZWApplication.getApplication().getString(R.string.zw_dialog_error_rng); ZiftrDialogManager.showSimpleAlert(rngError); } byte[] salt = new byte[SALT_LENGTH]; random.nextBytes(salt); String saltHex = ZiftrUtils.bytesToHexString(salt); try { ZLog.log("salt: " + salt); } catch (Exception e) { System.out.println("salt: " + saltHex); } return saltHex; } catch (Exception e) { throw new ZWKeyCrypterException("Unable to generate salt", e); } }
@Override public ZWEncryptedData encrypt(String clearText) throws ZWKeyCrypterException { try { Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM); byte[] iv = generateIv(encryptionCipher.getBlockSize()); String ivHex = ZiftrUtils.bytesToHexString(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv); encryptionCipher.init(Cipher.ENCRYPT_MODE, this.secretKey, ivSpec); byte[] encryptedText = encryptionCipher.doFinal(clearText.getBytes("UTF-8")); String encryptedHex = ZiftrUtils.bytesToHexString(encryptedText); // Why are we appending these values? // AES requires a random initialization vector (IV). We save the IV // with the encrypted value so we can get it back later in decrypt() return new ZWEncryptedData(ivHex + encryptedHex); } catch (Exception e) { System.out.println("error message: " + e.getMessage()); throw new ZWKeyCrypterException("Unable to encrypt", e); } }
public static SecretKey generateSecretKey(String password, String salt) throws ZWKeyCrypterException { try { PBEKeySpec pbeKeySpec = new PBEKeySpec( password.toCharArray(), ZiftrUtils.hexStringToBytes(salt), PBE_ITERATION_COUNT, KEY_LENGTH); SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM); SecretKey tmp = factory.generateSecret(pbeKeySpec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), SECRET_KEY_ALGORITHM); return secret; } catch (Exception e) { throw new ZWKeyCrypterException("Unable to get secret key", e); } }
@Override public byte[] decryptToBytes(ZWEncryptedData encryptedData) throws ZWKeyCrypterException { return ZiftrUtils.hexStringToBytes(decrypt(encryptedData)); }