CryptoJS Triple DES代码与Java等效

时间:2019-05-12 07:48:54

标签: java encryption cryptography

我有以下用于加密和解密的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此处已提出的大多数现有问题,但并没有帮助。

我发现了另一篇文章和示例代码,看起来似乎可以,但是没有用。

文章链接:https://androidfreetutorial.wordpress.com/2017/03/14/android-encryptiondecryption-with-tripledes-3des-algorithm/

我收到以下错误消息:

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

1 个答案:

答案 0 :(得分:1)

您使用的转换似乎对Triple-DES无效。

更改此字符串的填充:

public static String ALGO = "DESede/ECB/PKCS7Padding";

放入 PKCS5Padding

public static String ALGO = "DESede/ECB/PKCS5Padding";

您收到的编译器错误消息非常清楚; 无此类算法异常。编译器通常会遇到错误描述信息不佳的情况,但是在这种情况下,它会将您直接指向错误源。通过进行一些不错的老式网络搜索,您将意识到Triple DES需要PKCS 5 填充或完全不填充。

我从哪里获得此信息?当然来自文档

查看以下屏幕截图:enter image description here

有关Java Cipher对象的文档可以在here中找到。您可以看到调用Cipher.init(int opmode, Key key)的参数之一显然是Key类型。

通过单击相关链接以了解Key接口,您会注意到(此接口的)实现类之一是SecretKeySpec。可以在here中找到SecretKeySpec的文档。

SecretKeySpec的第一段:

  

此类仅适用于原始秘密密钥,这些原始密钥可以表示为字节数组,并且没有与之关联的密钥参数,例如 DES或Triple DES 密钥。