LoginSignup
0
0

More than 1 year has passed since last update.

【Web Crypto API】共通鍵暗号方式で暗号化と復号化をしてみた!

Last updated at Posted at 2022-09-27

はじめに

javascriptの暗号化で検索をかけるとcrypto-jsを使用した暗号化、復号化の記事がまずヒットします。
ただ、Webの標準機能できないか探していたところ「Web Crypto API」を見つけました。
今回はこれを使用した暗号化、復号化を試してみます。

注意

Web Crypto APIを使用して暗号化する場合には注意が必要です。
詳細は下記を参照してください。
mdn web docs:Web Crypto API

プログラム上の注意

ivですが特定のkeyで再利用をしてはいけないです。
詳しくはAesGcmParamsのPropertiesをご確認下さい。
mdn web docs:AesGcmParams#properties

結論

※今回は試すだけでしたので一つのプログラム上で暗号、復号しています。

document.addEventListener('DOMContentLoaded', async function() {
  const iv = await window.crypto.getRandomValues(new Uint8Array(12));
  const commonKey = await generateCommonKey();
  const encodedMessage = await encodingMessages();
  const encryptMessage = await encryptingMessages(commonKey,iv,encodedMessage);
  const decryptMessage = await decryptingMessages(commonKey,iv,encryptMessage);
  const decodedMessages = await decodingMessages(decryptMessage);
  console.log(decodedMessages); // encodeした「hello」が出力された
});

/**
 * 共通鍵の生成
 *
 * @return CryptoKey
 */
async function generateCommonKey() {
  let key = await window.crypto.subtle.generateKey(
    {
      name: "AES-GCM",
      length: 256
    },
    true,
    ["encrypt", "decrypt"]
  );
  return key;
}

/**
 * メッセージをencode
 *
 * @return Uint8Array
 */
function encodingMessages() {
  const message = "hello";
  const enc = new TextEncoder();
  return enc.encode(message);
}

/**
 * encodeしたメッセージ暗号化
 *
 * @param {CryptoKey} commonKey 共通鍵
 * @param {Uint8Array} iv
 * @param {Uint8Array} encodedMessage encodeされたメッセージ
 * @return ArrayBuffer
 */
async function encryptingMessages(commonKey,iv,encodedMessage) {
  return await window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    commonKey,
    encodedMessage,
  );
}

/**
 * 暗号化したメッセージを復号
 * 
 * @param {CryptoKey} commonKey 共通鍵
 * @param {Uint8Array} iv
 * @param {Uint8Array} encryptMessage 暗号化されたメッセージ
 * @return ArrayBuffer
 */
async function decryptingMessages(commonKey,iv,encryptMessage) {
  return await window.crypto.subtle.decrypt(
    { name: "AES-GCM", iv },
    commonKey,
    encryptMessage,
  );
}

/**
 * encodeされているメッセージをdecode
 * 
 * @param {ArrayBuffer} decryptMessage 復号されたメッセージ
 * @return string
 */
function decodingMessages(decryptMessage) {
  const dec = new TextDecoder();
  return dec.decode(decryptMessage);
}

参考文献

mdn web docs:Web Crypto API
mdn web docs:SubtleCrypto.generateKey()
mdn web docs:Crypto.getRandomValues()
mdn web docs:TextEncode.encode()
mdn web docs:TextDecoder.decode()
mdn web docs:SubtleCrypto.encrypt()
mdn web docs:SubtleCrypto.decrypt()

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0