如何使用crypto-js解密AES ECB

win*_*nut 4 javascript ecb

我试图在服务器端将加密数据从闪存(客户端)发送到javascript(在asp中作为jscript运行).

有几个javascript Aes库,但它们几乎没有文档.我正在尝试使用crypto-js,但无法使代码工作.下面的例子生成一个空输出,它应该生成"6bc1bee22e409f96e93d7e117393172a".

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-ecb.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script>
<script>
    var key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c');
    var data = CryptoJS.enc.Hex.parse('3ad77bb40d7a3660a89ecaf32466ef97');
    var decrypted3 = CryptoJS.AES.decrypt(data, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });
    document.write("<br /> dec3: " + decrypted3.toString());
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我从http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors中获取了记录的工作密钥和加密数据.

我正在使用ECB,因为它是唯一不需要IV或盐的版本,因为服务器不知道客户端上使用的IV或盐,因此无法解密数据.

有没有人知道为什么以上无法解密数据,或知道任何文档在哪里?

更新:经过几个小时的试验和错误后,我想出了一个产生输出的组合:7c121d95a84573b6120ada2ffff1ce3118561eba40555c0b但是,这仍然是不正确的.为实现这一目标所做的改变是:

 var decrypted3 = CryptoJS.AES.decrypt('3ad77bb40d7a3660a89ecaf32466ef97', key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });
Run Code Online (Sandbox Code Playgroud)

即我将数据作为一个十六进制的字符串传递,这是正确的,但至少产生输出.

下一个问题是填充问题.在客户端我使用AS3 hurlant库,它只提供两种填充策略:NONE和PKCS#5.在crypto-js中,可用的策略是:

Pkcs7 (the default)
Iso97971
AnsiX923
Iso10126
ZeroPadding
NoPadding 
Run Code Online (Sandbox Code Playgroud)

这是否意味着两个库之间没有机会解密数据?在我不得不编写自己的填充黑客(在AS3和java之间),添加或删除尾随数据之前,这需要几天的试验和错误的二进制数据 - 必须有一种更简单的方法从客户端发送单个加密字符串到服务器.

SSL不是一个选项,因为客户端用户只需使用Charles代理或类似功能即可查看和篡改未加密的数据.

fre*_*ckf 7

以下示例使用AES和ECB返回所需的输出.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script>
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-ecb.js"></script>
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script>


    <script>
        var encrypted = '3ad77bb40d7a3660a89ecaf32466ef97',
            key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c'),
            cipherParams = CryptoJS.lib.CipherParams.create({
                ciphertext: CryptoJS.enc.Hex.parse(encrypted)         
            });

        var decrypted3 = CryptoJS.AES.decrypt(cipherParams, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });
        document.write("<br /> dec3: " + CryptoJS.enc.Hex.stringify(decrypted3));
    </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

唯一真正的区别是使用CryptoJS.lib.CipherParams.create()创建一个cypherParams对象.根据官方文档,cypherParams对象"允许您访问加密期间使用的所有参数",包括key,iv,salt和原始cypherText.基本上所有解密它所需的信息.在我们的例子中,我们需要仅使用cypherText属性将加密数据转换为cypherParam.顺便提一下,cypherParam可以使用标准格式进行字符串化,这是它与其他系统的通信方式.

关于填充,据我所知,Pkcs7是Pkcs5的扩展,应该适用于使用Pkcs5创建的任何密码.当我在没有NoPadding选项的情况下尝试上面的代码示例(默认为Pkcs7)时,它不起作用,但我不知道在创建加密数据时使用了什么.至少您链接的AES测试向量页面没有告诉我们.


win*_*nut 4

放弃了 ECB,尝试了 CBC 的各种排列,并得到了其中一种。似乎也可以将 IV 以纯文本形式从客户端发送到服务器。

这是正确输出“6bc1bee22e409f96e93d7e117393172a”的版本。震惊。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script>
<!--script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-cbc.js"></script-->
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script>
<script>
    var key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c');
    var iv = CryptoJS.enc.Hex.parse('000102030405060708090A0B0C0D0E0F');
    var data = CryptoJS.enc.Hex.parse('7649abac8119b246cee98e9b12e9197d');      

    var encrypted = {};
    encrypted.key=key;
    encrypted.iv=iv;
    encrypted.ciphertext = data;

    var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.NoPadding });

    document.write("<br /> dec3: " + CryptoJS.enc.Hex.stringify(decrypted));
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)