@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);
    }
  }
 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));
 }