【JavaScript】テキストやファイルをE2E暗号化して保存する方法
作成日時 2023/09/12 11:37
最終更新 2023/09/12 12:01
最終更新 2023/09/12 12:01
まず初めに
暗号化
復号
本記事では、JavaScriptでCryptoJSを用いてファイルを暗号化・復号するプログラムを掲載させて頂きます。
CryptoJSを利用するため、headで以下のスクリプトを読み込んで下さい。
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
暗号化
// 暗号化するファイル(input)
var file = _("file").files[0];
// パスワード
var password = "password";
// ファイルを読み取って暗号化
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
var salt = CryptoJS.lib.WordArray.random(128 / 8);
var iv = CryptoJS.lib.WordArray.random(128 / 8);
var enc = CryptoJS.enc.Hex.stringify(salt) + "," + CryptoJS.enc.Hex.stringify(iv) + "," +
CryptoJS.AES.encrypt(
CryptoJS.enc.Utf8.parse(reader.result),
CryptoJS.PBKDF2(
CryptoJS.enc.Utf8.parse(password),
salt,
{
keySize: 128 / 8,
iterations: 500
}
),
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// inputの選択しているファイルを暗号データに置き換える
let list = new DataTransfer();
list.items.add(new File([enc], file.name));
_("file").files = list.files;
// formをPOSTする処理
// (略)
}
復号
// ファイルダウンロード用の関数
function DownloadFile(fileurl, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", fileurl);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function (evt) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(xhr.response);
}
}
}
xhr.send();
}
// ファイルをダウンロード
var password = "password";
var fileurl = "https://example.com/example-encrypted.png";
var FileName = "example-cncrypted.png";
DownloadFile(fileurl, function (result) {
window.decryptionarray = [];
window.decryptionarray[0] = String.fromCharCode.apply("", new Int8Array(result.slice(0, 32)));
window.decryptionarray[1] = String.fromCharCode.apply("", new Int8Array(result.slice(33, 65)));
window.decryptionarray[2] = "";
var uint8Arr = new Int8Array(result.slice(66));
for (var i = 0; i < uint8Arr.length; i += 1024)
window.decryptionarray[2] += String.fromCharCode.apply(null, uint8Arr.slice(i, i + 1024));
var salt = CryptoJS.enc.Hex.parse(window.decryptionarray[0]);
var iv = CryptoJS.enc.Hex.parse(window.decryptionarray[1]);
try {
// 復号してダウンロード
DownloadFileFromBlobURL(
CryptoJS.AES.decrypt(
{
"ciphertext": CryptoJS.enc.Base64.parse(window.decryptionarray[2])
},
CryptoJS.PBKDF2(
CryptoJS.enc.Utf8.parse(password),
salt,
{
keySize: 128 / 8,
iterations: 500
}
),
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
).toString(CryptoJS.enc.Utf8),
FileName
);
} catch (e) {
// パスワードが異なっている場合の処理
}
});
// blobのURLからダウンロードする関数
function DownloadFileFromBlobURL(blob, filename) {
const a = document.createElement("a");
document.body.appendChild(a);
a.download = filename;
a.href = blob;
a.click();
a.remove();
}