potpro (ぽとぷろ)
Full-stuck engineer(Not Full-stack)
JS/PHP/Go/Docker/Nginxなど。技術または趣味寄りの発信ブログです。
全 85 記事CryptoJSで文字や画像をAES暗号化したりする
CryptoJSで文字や画像をAES暗号化したりする
ネタが無いので、ありきたりだけどちょっと前にやってたことをブログに書こう。
CryptoJSはクライアントサイド(つまりはブラウザ上)でAESなんかを使った暗号化が可能なJavascriptライブラリです。
SHA-1などのハッシュ関数もあり、クライアント上でお手軽暗号化が実装できます。 使うのか知らないですがRIPEMDとかSHA-3まで対応してます。
文字列のAES暗号化・複合
SHA-2でパスフレーズをハッシュ化し、文字列をbase64エンコードしAES暗号化します。
ここまでやればまずパスフレーズがわからないなら暗号が破られることはないでしょう。
こんな感じのhtmlを用意。html部分は省略します。
上がパスフレーズ、下が暗号化する文字列です。 めんどいので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));
});
};
そのまま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));
});
};
複合したDataURIスキーマをクリックするとちゃんと画像が表示され、問題なく複合できていることがわかります。
しかし画像はそもそも文字と比べると容量がケタ違いですので、300KB程度では一瞬ですが、 数MBの画像を処理したりすると時間掛かるかもしれないです。
これをそのまま受け渡したりサーバに投げて処理できれば、暗号化した通信がhttps無しで実装できますね!まあhttps使えばいいじゃんって話ですが。