首页 > 解决方案 > java中密码的加密解密问题

问题描述

嗨,我正面临解密问题。解密后的值与原始值不匹配。

这是我的逻辑encryption

public byte[] encrypt(String plainText) {

    byte iv[] = new byte[ENCRYPTION_PARAM_SIZE];
    SecureRandom secRandom = new SecureRandom();
    secRandom.nextBytes(iv);
    
    Cipher cipher = Cipher.getInstance(ENCRYPTION_INSTANCE);
    SecretKeySpec key = new SecretKeySpec(fixSecret(encryptionKey), ENCRYPTION_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
    return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
}

这是我的逻辑Decryption

public String decrypt(byte[] cipherText) {

    byte iv[] = new byte[ENCRYPTION_PARAM_SIZE];
    SecureRandom secRandom = new SecureRandom();
    secRandom.nextBytes(iv);
    
    Cipher cipher = Cipher.getInstance(ENCRYPTION_INSTANCE);
    SecretKeySpec key = new SecretKeySpec(fixSecret(encryptionKey), ENCRYPTION_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    return new String(cipher.doFinal(cipherText), StandardCharsets.UTF_8);

}

加密选项:

ENCRYPTION_ALGORITHM = "DESede";
ENCRYPTION_INSTANCE = "DESede/CBC/PKCS5Padding";
Integer ENCRYPTION_PARAM_SIZE = 8;

这就是我试图验证的方式:

public static void main(String[] args){    
    Long value = 9123456L;
    String strval = value.toString();
    byte[] encryptedVal = encrypt(strval);
    String decryptedVal = decrypt(encryptedVal);
    
    System.out.println("Original  value : " +strval);
    System.out.println("Encrypted value : " +encryptedVal.toString());
    System.out.println("Decrypted value : " +decryptedVal);
    System.out.println("Final     value : " +Long.parseLong(decryptedVal));
}

我需要在这里做些什么才能让它发挥作用。

注意:如果我在没有 SecureRandom 的情况下使用以下逻辑,则上面的代码可以正常工作:

cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[ENCRYPTION_PARAM_SIZE]));

标签: javaencryptioncryptography

解决方案


在解密函数中,您生成一个随机初始化向量 (IV),因此这将永远不起作用。您需要存储加密函数中的 IV,并将其作为解密函数的输入提供。

这是一个例子:

public byte[] encryptAndDecrypt(String plainText) {

  byte iv[] = new byte[ENCRYPTION_PARAM_SIZE];
  SecureRandom secRandom = new SecureRandom();
  secRandom.nextBytes(iv);

  Cipher cipher = Cipher.getInstance(ENCRYPTION_INSTANCE);
  SecretKeySpec key = new SecretKeySpec(fixSecret(encryptionKey), ENCRYPTION_ALGORITHM);
  cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
  byte[] cipherText=cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
  return decrypt(cipherText, iv)
}


public String decrypt(byte[] cipherText, byte[] iv) {

 Cipher cipher = Cipher.getInstance(ENCRYPTION_INSTANCE);
 SecretKeySpec key = new SecretKeySpec(fixSecret(encryptionKey), ENCRYPTION_ALGORITHM);
 cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
 return cipher.doFinal(cipherText);
}

请注意,根据定义,IV 应该是随机的,但不应被视为机密,因此您可以将其存储为纯数据而无需任何保护。IV 背后的想法是随机化密文,因此如果您不使用 IV,或使用常量 IV,并加密“X”,密文为“Y”,您可以轻松地将密文反转为纯文本,而使用随机IV,密文每次都不同。


推荐阅读