5

暗号化されたデータをフラッシュ (クライアント側) からサーバー側の 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から文書化された作業キーと暗号化されたデータを取得しました

サーバーはクライアントで使用されるIVまたはソルトを認識しないため、IVまたはソルトを必要としない唯一のバージョンであるため、ECBを使用しているため、データを復号化できません。

上記がデータの復号化に失敗した理由、またはドキュメントの場所を知っている人はいますか?

更新: 数時間の試行錯誤の後、出力を生成する組み合わせを思いつきました: 7c121d95a84573b6120ada2ffff1ce3118561eba40555c0b ただし、これはまだ正しくありません。これを生成するために行われた変更は次のとおりです。

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

つまり、データを 16 進数の文字列として渡しましたが、これは正しくありませんが、少なくとも出力は生成されます。

次の問題はパディングの問題です。クライアントでは、NONE と PKCS#5 の 2 つのパディング戦略のみを提供する AS3 hurlant ライブラリを使用しています。crypto-js で利用可能な戦略は次のとおりです。

Pkcs7 (the default)
Iso97971
AnsiX923
Iso10126
ZeroPadding
NoPadding 

これは、2 つのライブラリ間でデータを復号化する機会がなくなるということですか? 以前は、独自のパディング ハック (AS3 と Java の間) を作成して末尾のデータを追加または削除する必要がありましたが、これにはバイナリ データで数日間の試行錯誤が必要でした。クライアントから単一の暗号化された文字列を送信するより簡単な方法が必要です。サーバーへ。

SSL はオプションではありません。クライアント ユーザーは単純に Charles プロキシなどを使用して、暗号化されていないデータを表示して改ざんすることができます。

4

3 に答える 3

9

以下の例は、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、ソルト、および元の cypherText を含む「暗号化中に使用されるすべてのパラメーターへのアクセスを提供します」。基本的に、それを解読するために必要なすべての情報。この場合、暗号化されたデータを cypherText プロパティのみを使用して cypherParam に変換する必要がありました。ちなみに、cypherParam は標準形式を使用して文字列化できます。これは、他のシステムと通信する方法です。

パディングに関しては、私が理解しているように、Pkcs7 は Pkcs5 の拡張であり、Pkcs5 を使用して作成されたすべての暗号で機能するはずです。NoPadding オプション (デフォルトは Pkcs7) を指定せずに上記のコード サンプルを試してみたところ、機能しませんでしたが、暗号化されたデータの作成に何が使用されたのかわかりません。少なくとも、リンク先の AES テスト ベクトル ページではわかりません。

于 2013-11-24T01:40:51.457 に答える
4

ECB をあきらめ、CBC でさまざまな順列を試し、そのうちの 1 つが機能するようになりました。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>
于 2013-01-15T00:45:49.673 に答える
0

これは、更新された 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>
于 2016-11-21T12:10:38.953 に答える