Web CryptoでJavaScriptだけでパスワードによる暗号化/復号
やりたいこと
やりかた
code:js
async function encryptThenDecrypt(salt = "the salt is this random string") {
const raw = 'this is a secret';
const password = 'mysecretpassword';
const importedPassword = await window.crypto.subtle.importKey(
"raw",
stringToUint8Array(password),
{ name: "PBKDF2" },
false,
);
const key = await window.crypto.subtle.deriveKey({
name: "PBKDF2",
salt: stringToUint8Array(salt),
iterations: 100000,
hash: "SHA-256"
},
importedPassword, {
name: "AES-GCM",
length: 128
},
false,
);
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const encrypted = await window.crypto.subtle.encrypt({
name: "AES-GCM",
iv: iv,
}, key, stringToUint8Array(raw));
const encrypted_data = new Uint8Array(encrypted);
const decrypted = await window.crypto.subtle.decrypt({
name: "AES-GCM",
iv: iv,
}, key, encrypted_data);
return Decrypted data: ${uint8ArrayToString(decrypted)};
}
function stringToUint8Array(str) {
return new TextEncoder("utf-8").encode(str);
}
function uint8ArrayToString(buffer) {
return new TextDecoder("utf-8").decode(buffer);
}
encryptThenDecrypt().then(console.log);
code:出力
Decrypted data: this is a secret
rawが暗号化したい平文。
passwordがパスワード文字列。
window.crypto.subtle.deriveKey()にはsaltとiterationsは必須。
おそらくPBKDF2だからだと思う。
iterationsが100000というのは大きすぎるのかもしれないので要調査。 hr.icon