我有以下用于加密和解密的CryptoJS代码。
加密代码
<script type="text/javascript">
$(document).on("click", "#crack", function(evt) {
evt.preventDefault();
var e = $("#plaintext").val();
var key = $("#key").val();
var iv = CryptoJS.enc.Utf8.parse(key);
var r, t = CryptoJS.enc.Utf8.parse(key), // key
n = CryptoJS.DES.encrypt(CryptoJS.enc.Utf8.parse(e), t,{
iv:iv,
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
r = n.toString(CryptoJS.enc.Utf8);
$(".result").text(n);
});
</script>
解密代码
<script type="text/javascript">
$(document).on("click", "#crack", function(evt) {
evt.preventDefault();
var e = $("#ciphertext").val();
var key = $("#key").val();
var r, t = CryptoJS.enc.Utf8.parse(key), // key
n = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(e.replace('"', ""))
}, t, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}),
r = n.toString(CryptoJS.enc.Utf8);
$(".result").text(r);
});
</script>
我想在Java中重新创建相同的逻辑,但效果不佳。我遵循了StackOverflow此处已提出的大多数现有问题,但并没有帮助。
我发现了另一篇文章和示例代码,看起来似乎可以,但是没有用。
我收到以下错误消息:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/ECB/PKCS7Padding
我在做什么错,这里的CryptoJS代码与Java代码有何不同?
示例输入:
键:
CipherText: 3OwGE1y7zFLyPT49uGMvFQ ==
密钥: 75a1b1ae20af8de7bdfb6fac8ca9d36c0ab91930
编辑:添加了工作代码。同样,CryptoJS是简单DES,而不是@James建议的三重DES。我测试的应用程序在资源文件中使用了Tripledes.js,这使我误以为也许使用了Triple DES。我在CryptoJS中进行了交叉检查,如果您想使用TripleDES,则必须使用类似CryptoJS.TripleDES.encrypt(...)
的东西。另外,我忘记了DES密钥的大小是8个字节,并且给我的密钥没有得到正确的处理,导致了不好的填充异常,这是我使用Arrays.copyOf解决的方法,最后要感谢P.Soutzikevich。
以下代码完全符合我的要求。
private final int DES_KEY_SIZE = 8;
private final String DES_MODE = "DES/ECB/PKCS5Padding";
加密
byte[] keyBytes = Arrays.copyOf(secretKey.getBytes(), DES_KEY_SIZE);
byte[] plainTextBytes = plainText.getBytes();
desKeySpec = new SecretKeySpec(keyBytes, "DES");
desCipher = Cipher.getInstance(DES_MODE);
desCipher.init(Cipher.ENCRYPT_MODE, desKeySpec);
byte[] encryptedText = desCipher.doFinal(plainTextBytes);
data = Base64.getEncoder().encodeToString(encryptedText);
解密:
byte[] keyBytes = Arrays.copyOf(secretKey.getBytes(), DES_KEY_SIZE);
byte[] encryptedTextBytes = Base64.getDecoder().decode(cipherText);
desKeySpec = new SecretKeySpec(keyBytes, "DES");
desCipher = Cipher.getInstance(DES_MODE);
desCipher.init(Cipher.DECRYPT_MODE, desKeySpec);
data = new String(desCipher.doFinal(encryptedTextBytes));
答案 0 :(得分:1)
您使用的转换似乎对Triple-DES无效。
更改此字符串的填充:
public static String ALGO = "DESede/ECB/PKCS7Padding";
放入 PKCS5Padding :
public static String ALGO = "DESede/ECB/PKCS5Padding";
您收到的编译器错误消息非常清楚; 无此类算法异常。编译器通常会遇到错误描述信息不佳的情况,但是在这种情况下,它会将您直接指向错误源。通过进行一些不错的老式网络搜索,您将意识到Triple DES需要PKCS 5 填充或完全不填充。
我从哪里获得此信息?当然来自文档。
有关Java Cipher
对象的文档可以在here中找到。您可以看到调用Cipher.init(int opmode, Key key)
的参数之一显然是Key
类型。
通过单击相关链接以了解Key
接口,您会注意到(此接口的)实现类之一是SecretKeySpec
。可以在here中找到SecretKeySpec的文档。
SecretKeySpec的第一段:
此类仅适用于原始秘密密钥,这些原始密钥可以表示为字节数组,并且没有与之关联的密钥参数,例如 DES或Triple DES 密钥。