java - 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]));
解决方案
在解密函数中,您生成一个随机初始化向量 (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,密文每次都不同。
推荐阅读
- javascript - 如何自动刷新烧瓶
- javascript - puppeteer page.click(
) 但找不到 - angular - 选择侧边栏项目不显示组件
- jupyter - 服务器中的jupyter notebook如何安装unix2dos?
- javascript - 如何让客户端通过 tcp 接收图像?
- android - react native中的react导航,双击时如何让对讲读取选项卡的名称?
- google-apps-script - 如何编写脚本以启用 Google Docs(谷歌应用程序)中的链接?
- python - 列表数组的格式化
- javascript - React-rating-rating-stars-component 值不会改变
- amazon-web-services - 我们是否可以通过某种方式查看现有 QuickSight 报告和仪表板的使用情况统计信息?