1

SJCL を使用する RNCryptor を使用します。16 進メッセージを復号化しようとしていますが、CBC モードを使用すると、状況がおかしくなります。どうやら、CBC を使用するときに beware ステートメントを宣言する必要があり、エラーが発生します。

function KeyForPassword(password, salt) {
    console.log("Creating key...");
    var hmacSHA256 = function (password) {
        var hasher = new sjcl.misc.hmac(password, sjcl.hash.sha256);
        this.encrypt = function () {
            return hasher.encrypt.apply(hasher, arguments);
        };
    };
    return sjcl.misc.pbkdf2(password, salt, 10000, 32 * 8, hmacSHA256);
};


function decrypt(password, message, options) {

    message = sjcl.codec.hex.toBits(message);

    options = options || {};

    var version = sjcl.bitArray.extract(message, 0 * 8, 8);
    var options = sjcl.bitArray.extract(message, 1 * 8, 8);

    var encryption_salt = sjcl.bitArray.bitSlice(message, 2 * 8, 10 * 8);
    var encryption_key = _this.KeyForPassword(password, encryption_salt);

    var hmac_salt = sjcl.bitArray.bitSlice(message, 10 * 8, 18 * 8);
    var hmac_key = _this.KeyForPassword(password, hmac_salt);

    var iv = sjcl.bitArray.bitSlice(message, 18 * 8, 34 * 8);

    var ciphertext_end = sjcl.bitArray.bitLength(message) - (32 * 8);
    var ciphertext = sjcl.bitArray.bitSlice(message, 34 * 8, ciphertext_end);

    var hmac = sjcl.bitArray.bitSlice(message, ciphertext_end);
    var expected_hmac = new sjcl.misc.hmac(hmac_key).encrypt(sjcl.bitArray.bitSlice(message, 0, ciphertext_end));

    // .equal is of consistent time
    if (! sjcl.bitArray.equal(hmac, expected_hmac)) {
      throw new sjcl.exception.corrupt("HMAC mismatch or bad password.");
    }

    var aes = new sjcl.cipher.aes(encryption_key);
    sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]()
    var decrypted = sjcl.mode.cbc.decrypt(aes, ciphertext, iv);


    return decrypted.toString(CryptoJS.enc.Utf8);
};

ソルト、キー、およびハッシュに関して、すべてが Python 側の暗号化と一致します。しかし、私はこのエラーが発生します:

TypeError: Cannot read property 'CBC mode is dangerous because it doesn't protect message integrity.' of undefined

このメソッドは非推奨になっていると思われるため、この CryptoJS メソッドを使用しようとしました。

var decrypted = CryptoJS.AES.decrypt(ciphertext, encryption_key, {iv:iv});

これは空白の文字列を返しました。

私は本当に近づいているように感じます。この最後の部分で助けが必要です。ありがとう。

4

2 に答える 2

1

SJCL

GitHub の configureを調べると、ビルド済みの sjcl.js に CBC は含まれていません。CBC ファイル (core/cbc.js) をページに個別に含める必要があります。または、configureファイルを操作して、有効なモジュールのリストに cbc を追加する必要があります。

CryptoJS

decrypted空文字列ではありません。の負の数を持つオブジェクトをCryptoJS.<cipher>.decrypt()返します。このプロパティは、に含まれると予想されるバイト数を示します。負の数は、何かがうまくいかなかったことを意味します。常に負の数である必要はありません。WordArraysigBytesWordArray

いくつかの問題が発生する可能性があります:

  • あなたは正しい鍵を持っていません。
  • 適切にスライスされた暗号文がありません。
  • ciphertextOpenSSL 形式の文字列ではないか、CipherParamsオブジェクトではありません。{ciphertext: ciphertext}代わりにパスしてみてください。
  • キーと IV の形式が正しくありませんWordArray。オブジェクトである必要があります。
于 2015-08-25T08:29:43.890 に答える
0

Artjom B. が述べたように、cbc.jsbitArray.js (復号化に必要な部分であり、私が見逃していたもの) が必要です。元のコードは正常に動作します。

余談ですが、Rob Napier が指摘したように、PBKDF2 の反復回数は遅いです。ただし、このケース (復号化) では、10K カウントはすぐに機能しましたが、暗号化のために、代わりに 1000 回の反復で CryptoJS の PBKDF2 を使用して kdf を補足しました (sjcl で bitArray エラーが発生していました)。

于 2015-10-02T01:47:22.200 に答える