CryptoJSで文字や画像をAES暗号化したりする

CryptoJSで文字や画像をAES暗号化したりする

author potpro(ぼとぷろ)
2015/10/13

CryptoJSで文字や画像をAES暗号化したりする

ネタが無いので、ありきたりだけどちょっと前にやってたことをブログに書こう。

CryptoJSはクライアントサイド(つまりはブラウザ上)でAESなんかを使った暗号化が可能なJavascriptライブラリです。

SHA-1などのハッシュ関数もあり、クライアント上でお手軽暗号化が実装できます。 使うのか知らないですがRIPEMDとかSHA-3まで対応してます。

文字列のAES暗号化・複合

SHA-2でパスフレーズをハッシュ化し、文字列をbase64エンコードしAES暗号化します。

ここまでやればまずパスフレーズがわからないなら暗号が破られることはないでしょう。

こんな感じのhtmlを用意。html部分は省略します。

cryptjs 上がパスフレーズ、下が暗号化する文字列です。 めんどいのでjquery使ってます。

window.onload = function () {
    $("#set").on("click", function () {
        var text = $("#input").val();
        var str = CryptoJS.SHA256(text);
        var hashbase64 = str.toString(CryptoJS.enc.Base64);
        //AES
        var Message = $("#text").val();
        encrypt = CryptoJS.AES.encrypt(Message, hashbase64);
        console.log("aes encrypt:");
        console.log(encrypt.toString());
        decrypt = CryptoJS.AES.decrypt(encrypt, hashbase64);
        console.log("aes decrypt:");
        console.log(decrypt.toString(CryptoJS.enc.Utf8));
    });

};

cryptjs2 そのままbase64で出力できるのが便利です。 ※base64で出力するには、enc-base64-min.jsが必要です。

画像のAES暗号化・複合

画像も同じように、DataURIスキーマに変換すれば使えます。 アップロードした画像なんかを暗号化させたいので、 HTML5 File APIでまず画像を読み込んで処理します。

window.onload = function () {
    $("#imgset").on("change", function () {
        var filesrc = $(this).prop('files')\[0\];

        if (!filesrc) {
            console.error("No File Error!");
            return;
        } // ファイル未選択

        if (filesrc.size >= 307200) {
            console.error("File Size Over Error!");
            return;
        } // サイズ制限300KBまで

        console.log(filesrc);

        var fr = new FileReader();
        fr.onload = function () {
            src = fr.result; // 読み込んだ画像データをsrcにセット
            $('#preview\_field').attr('src', src);
        }
        fr.readAsDataURL(filesrc); // 画像読み込み
    });

    $("#imgupload").on("click", function () {
        var text = $("#input").val();
        var str = CryptoJS.SHA256(text);
        var hashbase64 = str.toString(CryptoJS.enc.Base64);
        //AES
        var Message = $("#preview\_field").attr('src');
        encrypt = CryptoJS.AES.encrypt(Message, hashbase64);
        console.log("aes encrypt:");
        console.log(encrypt.toString());
        decrypt = CryptoJS.AES.decrypt(encrypt, hashbase64);
        console.log("aes decrypt:");
        console.log(decrypt.toString(CryptoJS.enc.Utf8));
    });

};

cryptjs3

複合したDataURIスキーマをクリックするとちゃんと画像が表示され、問題なく複合できていることがわかります。

しかし画像はそもそも文字と比べると容量がケタ違いですので、300KB程度では一瞬ですが、 数MBの画像を処理したりすると時間掛かるかもしれないです。

これをそのまま受け渡したりサーバに投げて処理できれば、暗号化した通信がhttps無しで実装できますね!まあhttps使えばいいじゃんって話ですが。