簡體   English   中英

如何使用crypto-js解密AES ECB

[英]How to decrypt AES ECB using crypto-js

我正在嘗試將加密數據從閃存(客戶端)發送到服務器端的 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>

我從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 });

即我將數據作為十六進制字符串傳入,這不可能是正確的,但至少會產生輸出。

下一個問題將是填充問題。 在客戶端,我使用 AS3 hurant 庫,它只提供兩種填充策略:NONE 和 PKCS#5。 在crypto-js中,可用的策略是:

Pkcs7 (the default)
Iso97971
AnsiX923
Iso10126
ZeroPadding
NoPadding 

這是否意味着沒有機會在兩個庫之間解密數據? 在我不得不編寫自己的填充技巧(在 AS3 和 java 之間)來添加或刪除尾隨數據之前,但這需要數天的二進制數據試驗和錯誤 - 必須有一種更簡單的方法來從客戶端發送單個加密字符串到服務器。

SSL 不是一種選擇,因為客戶端用戶可以簡單地使用 Charles 代理或類似工具來查看和篡改未加密的數據。

下面的示例使用 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>

唯一真正的區別是使用 CryptoJS.lib.CipherParams.create() 創建一個 cypherParams 對象。 根據官方文檔,cypherParams 對象“使您可以訪問加密期間使用的所有參數”,包括密鑰、iv、salt 和原始密碼文本。 基本上解密它所需的所有信息。 在我們的例子中,我們只需要使用 cypherText 屬性將加密數據轉換為 cypherParam。 順便提一下,cypherParam 可以使用標准格式進行字符串化,這就是它與其他系統通信的方式。

關於填充,據我 所知,Pkcs7 是 Pkcs5 的擴展,應該適用於使用 Pkcs5 創建的任何密碼。 當我在沒有 NoPadding 選項(默認為 Pkcs7)的情況下嘗試上面的代碼示例時,它不起作用,但我不知道在創建加密數據時使用了什么。 至少您鏈接到的 AES 測試向量頁面沒有告訴我們。

放棄了 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>

這是一個有效且更新的答案,具有更新的 CDN 鏈接和一個將生成的解密數據轉換為明文的函數。

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    </head>
    <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/cipher-core.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/aes.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/mode-ecb.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/pad-nopadding.js"></script>


    <script>
    var encrypted = 'B655564D4428C56E7F9E44D81770CFDBC3FB0FCEA8FFDF7CC936FFE6C7A595A0FE085FAA65796C4C24D0862FAF56CAA1880DCD281A891DD1E999F953F2B669291B41B486E0FEC5E11BE7B7348703665081E4FF79F815C35803506468548F3C5EE13B5783A0E22D91E08CB1897E4D135DA8C4E650A1D51FFDDD210311A0835FD8E8EE08CC968F8A0B0EF811554872A093',
    key = CryptoJS.enc.Hex.parse('844AF9144552AFAE26A9C45FD5882718'),
    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 />" + hex2a(CryptoJS.enc.Hex.stringify(decrypted3)));
    function hex2a(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}
</script>
</body>
</html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM