【问题标题】:How to decrypt Triple Des CryptoJS values in Java class如何在 Java 类中解密 Triple Des CryptoJS 值
【发布时间】:2013-10-29 03:21:14
【问题描述】:

我被要求在将某些文本从客户端 (web) 发送到服务器端 (java) 之前对其进行加密

所以我尝试在客户端使用 CryptoJS 库。 我这样加密它:

    var key = "aaaaaaaaaaaaaaaaaaaaaaaa";
    var value = "KF169841";
    var encryptedString = CryptoJS.TripleDES.encrypt(value, key);
    console.log(encryptedString.toString());

我得到这样的东西:U2FsdGVkX19eYFFHgYGCr3v9/skTOKVp0pLWRNK9JTg= 我在其他Decrypt tool online(也使用 CryptoJS)中使用了这个 encryptedString 和密钥,并得到了 KF169841 的确切值。

将此值和密钥发送到服务器后(虽然密钥不是直接发送到服务器,但为了测试,它是),我需要使用 Java 对其进行解密。 但我完全不知道如何解密它。我从谷歌搜索中尝试了一些代码,但如果使用 DESese,它最终会出现错误的填充,或者如果我使用 ECB/NoPadding,则会得到错误的值。 我确实尝试过为 CryptoJS 端设置 sfg 之类的东西:

    mode: CryptoJS.mode.EBC,
    padding: CryptoJS.pad.NoPadding

但是他们得到了 javascript 异常(a 没有定义)

那么任何有 CryptoJS 经验的人都可以帮助我使用 java 解密这个吗?

================================================ ===============

更新:对不起,我正在使用我的服务器端代码

/**
     * Method To Decrypt An Ecrypted String
     */
    public String decrypt(String encryptedString, String myEncryptionKey) {
        String decryptedText = null;
        try {
            byte[] keyAsBytes = myEncryptionKey.getBytes("UTF8");
            KeySpec myKeySpec = new DESedeKeySpec(keyAsBytes);
            SecretKeyFactory mySecretKeyFactory = 
                    SecretKeyFactory.getInstance("DESede");
            Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
            SecretKey key = mySecretKeyFactory.generateSecret(myKeySpec);

            cipher.init(Cipher.DECRYPT_MODE, key);
//            BASE64Decoder base64decoder = new BASE64Decoder();
//            byte[] encryptedText = base64decoder.decodeBuffer(encryptedString);

            byte[] encryptedText =  org.apache.commons.codec.binary.Base64.decodeBase64(encryptedString);
            byte[] plainText = cipher.doFinal(encryptedText);
            decryptedText= bytes2String(plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptedText;
    }

【问题讨论】:

  • 欢迎来到 StackOverflow。您使用的是 Java 还是 Javascript?它们不是一回事。
  • 我在客户端使用javascript(使用CryptoJS lib)来加密它对于服务器端我需要使用Java使用密钥解密值
  • @ChristianTernus:两者都有。
  • 好的,很酷;我们可以看看你目前的 Java 代码吗?
  • encryptedString 是一个 JSON 对象。您需要先从 JSON 对象中提取密文,然后才能进行解密。

标签: java encryption tripledes cryptojs


【解决方案1】:

根据the documentation,您的encryptedString 变量包含必须拆分才能发送到Java 代码的结构化数据。您需要将encryptedString.ivencryptedString.ciphertext 发送到您的Java 代码。如果您继续使用密码(见下文),您还需要发送encryptedString.salt

如果您将密钥作为字符串传递,它将被解释为 密码,并且会从中派生一个密钥。如果您确实想传递一个显式密钥,请按照documentation 并按照下面的代码 sn-p 的建议指定 IV 和密钥。如果您坚持提供密码,那么您必须弄清楚派生方案并在您的 Java 代码中使用相同的过程。

// Code snippet from http://code.google.com/p/crypto-js/#Custom_Key_and_IV
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
    var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
    var iv  = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');

    var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
</script>

关于您的 Java 代码,它看起来基本没问题(尽管字符串转换存在很大的错误空间)。但是,您可能希望将密钥从十六进制转换为二进制,而不是获取字节:

byte[] keyAsBytes = DatatypeConverter.parseHexBinary(myEncryptionKey);

这假设您更改了 JavaScript 代码以传递文字键值。

您还需要切换到DESede/CBC/PKCS5Padding 并将IVParameterSpec 对象传递给您的Cipher.init 调用,指定从您的Java 脚本代码发送的IV 值。

【讨论】:

  • 问题是我只允许将加密的字符串发送到服务器,没有别的。我仅在测试时将密钥发送到服务器(如我的帖子中所述)。用户之间的键也不同,因此我不能将其值固定为服务器端的某个字节 []。这就是为什么我需要将函数作为 CryptoJS.TripleDES.decrypt 接受 2 个字符串作为参数。
  • @mameo 我要说的是,对话的双方都需要使用相同的密钥并以相同的方式派生它。因此,如果您想在 CryptoJS 中继续使用密码,则需要将派生代码添加到 Java。您需要发送到 Java 服务器的最低要求是密文和 IV。如果你使用密码,你也需要发送盐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多