【发布时间】:2020-04-19 08:24:05
【问题描述】:
我正在尝试使用带有硬编码密钥的 DES/ECB/PKCS5Padding 算法在 Java 中加密相同的数据。我使用online tool 验证了我的加密值。如果我使用带有特殊字符的密钥,那么 Java 和 online tool 的加密值就不一样了。
如果我使用密钥 2b7e151628aed2a6abf71589 并输入文本 1234 则加密结果与online tool 相同。此文本使用 Java 的加密结果是 SRC/0ptoT78= 与online tool 相同,图片也附上供参考
但如果我使用密钥 /£½ZBÝy‚÷Í(Ó—&*Ænù;'³ 并再次输入文本 1234 则加密结果与 @ 不同987654326@。本文使用Java加密后的结果为UUoh48bB9dM=,与online tool不同,另附图片供参考
我的java代码如下
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.Key;
public class Main {
public static void main(String[] args) {
try {
System.out.println(encrypt("/£½ZBÝy‚÷Í( Ó—&*Ænù;‘³", "1234"));
System.out.println(encrypt("2b7e151628aed2a6abf71589", "1234"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String key, String str) throws Exception {
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
System.out.println(new String(key.getBytes(), "UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
Key secretKey = keyFactory.generateSecret(desKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
byte[] base64Bytes = Base64.encodeBase64(bytes);
return new String(base64Bytes);
}
public static String decrypt(String key, String str) throws Exception {
byte[] data =Base64.decodeBase64(str);
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(data);
return new String(decryptedBytes, "gb2312");
}
}
【问题讨论】:
-
DES 使用二进制密钥,而不是文本格式的密码。您应该以二进制形式提供您的密钥,例如字节数组或十六进制编码字符串。在线工具不允许您正确提供二进制 DES 密钥,这使得该工具对 DES 毫无用处。
-
此外,针对测试向量进行测试比针对糟糕的网站进行测试更有意义。
标签: java spring-boot encryption java-8 3des