Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Web Crypto

最終更新 Markdown で表示Agent セットアップ

背景

Web Crypto API は、一般的な暗号処理向けの低レベル関数セットを提供します。Workers ランタイムはこの API の全面を実装していますが、対応アルゴリズム は、多くのブラウザーの実装とは一部異なります。

Web Crypto API で暗号処理を行う方が、JavaScript だけで行うよりも大幅に高速です。CPU 負荷の高い暗号処理を行う場合は、Web Crypto API の利用を検討してください。

Web Crypto API は SubtleCrypto インターフェイスとして実装され、グローバルの crypto.subtle バインディング経由で使えます。ダイジェスト(ハッシュとも呼ばれます)を計算する簡単な例は次のとおりです。

const myText = new TextEncoder().encode('Hello world!');

const myDigest = await crypto.subtle.digest(
  {
    name: 'SHA-256',
  },
  myText // The data you want to hash as an ArrayBuffer
);

console.log(new Uint8Array(myDigest));

一般的な用途の 1 つに、リクエストへの署名 があります。


コンストラクター

  • crypto.DigestStream(algorithm) DigestStream

    • ストリーミングデータからハッシュダイジェストを生成できる、crypto API の非標準拡張です。DigestStream 自体は WritableStream であり、書き込まれたデータは保持しません。代わりに、データの流れが終わったときに、自動でハッシュダイジェストを生成します。

パラメーター

使い方

export default {
  async fetch(req) {
    // Fetch from origin
    const res = await fetch(req);

    // We need to read the body twice so we `tee` it (get two instances)
    const [bodyOne, bodyTwo] = res.body.tee();
    // Make a new response so we can set the headers (responses from `fetch` are immutable)
    const newRes = new Response(bodyOne, res);
    // Create a SHA-256 digest stream and pipe the body into it
    const digestStream = new crypto.DigestStream("SHA-256");
    bodyTwo.pipeTo(digestStream);
    // Get the final result
    const digest = await digestStream.digest;
    // Turn it into a hex string
    const hexString = [...new Uint8Array(digest)]
      .map(b => b.toString(16).padStart(2, '0'))
      .join('')
    // Set a header with the SHA-256 hash and return the response
    newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
    return newRes;
  }
}
export default {
  async fetch(req): Promise<Response> {
    // Fetch from origin
    const res = await fetch(req);

    // We need to read the body twice so we `tee` it (get two instances)
    const [bodyOne, bodyTwo] = res.body.tee();
    // Make a new response so we can set the headers (responses from `fetch` are immutable)
    const newRes = new Response(bodyOne, res);
    // Create a SHA-256 digest stream and pipe the body into it
    const digestStream = new crypto.DigestStream("SHA-256");
    bodyTwo.pipeTo(digestStream);
    // Get the final result
    const digest = await digestStream.digest;
    // Turn it into a hex string
    const hexString = [...new Uint8Array(digest)]
      .map(b => b.toString(16).padStart(2, '0'))
      .join('')
    // Set a header with the SHA-256 hash and return the response
    newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
    return newRes;
  }
} satisfies ExportedHandler;

メソッド

  • crypto.randomUUID() : string

    • RFC 4122 で定義された、新しいランダムな(バージョン 4)UUID を生成します。
  • crypto.getRandomValues(bufferArrayBufferView) : ArrayBufferView

    • 渡された ArrayBufferView を暗号学的に安全な乱数で埋め、buffer を返します。

パラメーター

  • bufferArrayBufferView

    • Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array である必要があります。

SubtleCrypto のメソッド

これらのメソッドは、すべて crypto.subtle 経由でアクセスします。詳細は MDN にも記載されています。

encrypt

  • encrypt(algorithm, key, data) : Promise<ArrayBuffer>

    • パラメーターとして与えた平文、アルゴリズム、キーに対応する暗号データを含む Promise を返します。

パラメーター

decrypt

  • decrypt(algorithm, key, data) : Promise<ArrayBuffer>

    • パラメーターとして与えた暗号文、アルゴリズム、キーに対応する平文データを含む Promise を返します。

パラメーター

sign

  • sign(algorithm, key, data) : Promise<ArrayBuffer>

    • パラメーターとして与えたテキスト、アルゴリズム、キーに対応する署名を含む Promise を返します。

パラメーター

verify

  • verify(algorithm, key, signature, data) : Promise<boolean>

    • パラメーターとして与えた署名が、同じくパラメーターとして与えたテキスト、アルゴリズム、キーと一致するかどうかを示す Boolean 値を含む Promise を返します。

パラメーター

  • algorithmstring | object

  • keyCryptoKey

  • signatureArrayBuffer

  • dataArrayBuffer

digest

  • digest(algorithm, data) : Promise<ArrayBuffer>

    • パラメーターとして与えたアルゴリズムとテキストから生成したダイジェストを含む Promise を返します。

パラメーター

generateKey

  • generateKey(algorithm, extractable, keyUsages) : Promise<CryptoKey> | Promise<CryptoKeyPair>

    • 対称アルゴリズムでは、新しく生成した CryptoKey を含む Promise を返します。非対称アルゴリズムでは、新しく生成した 2 つのキーを含む CryptoKeyPair を返します。たとえば、新しい AES-GCM キーを生成するには次のようにします。
    let keyPair = await crypto.subtle.generateKey(
      {
        name: 'AES-GCM',
        length: 256,
      },
      true,
      ['encrypt', 'decrypt']
    );

パラメーター

deriveKey

  • deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages) : Promise<CryptoKey>

    • パラメーターとして与えたベースキーと特定のアルゴリズムから導出した、新しく生成した CryptoKey を含む Promise を返します。

パラメーター

deriveBits

  • deriveBits(algorithm, baseKey, length) : Promise<ArrayBuffer>

    • パラメーターとして与えたベースキーと特定のアルゴリズムから導出した、疑似乱数ビットの新しいバッファーを含む Promise を返します。履行されると、導出したビットを含む ArrayBuffer になります。このメソッドは deriveKey() とよく似ていますが、deriveKey()ArrayBuffer ではなく CryptoKey オブジェクトを返します。実質的に、deriveKey()deriveBits() のあとに importKey() を続けたものです。

パラメーター

  • algorithmobject

  • baseKeyCryptoKey

  • lengthint

    • 導出するビット列の長さです。

importKey

  • importKey(format, keyData, algorithm, extractable, keyUsages) : Promise<CryptoKey>

    • 外部の移植可能な形式のキーを、Web Crypto API で使える CryptoKey に変換します。

パラメーター

exportKey

  • exportKey(formatstring, keyCryptoKey) : Promise<ArrayBuffer>

    • CryptoKeyextractable である場合、移植可能な形式に変換します。

パラメーター

wrapKey

  • wrapKey(format, key, wrappingKey, wrapAlgo) : Promise<ArrayBuffer>

    • CryptoKey を移植可能な形式に変換し、別のキーで暗号化します。これにより、信頼できない環境での保存や転送に適した形になります。

パラメーター

unwrapKey

  • unwrapKey(format, key, unwrappingKey, unwrapAlgo, 
    unwrappedKeyAlgo, extractable, keyUsages)
    : Promise<CryptoKey>

    • wrapKey() でラップされたキーを、再び CryptoKey に戻します。

パラメーター

timingSafeEqual

  • timingSafeEqual(a, b) : bool

    • タイミング攻撃に耐性のある方法で、2 つのバッファーを比較します。Web Crypto API の非標準拡張です。

パラメーター

  • aArrayBuffer | TypedArray

  • bArrayBuffer | TypedArray

対応アルゴリズム

Workers は WebCrypto 標準 のすべての操作を実装しています。内容は次の表のとおりです。

チェックマーク(✓)は、この機能が仕様どおりに完全対応していると見なせることを示します。
バツ(✘)は、この機能が仕様の一部だが未実装であることを示します。
機能が操作を部分的にだけ実装している場合は、詳細を記載します。

アルゴリズム sign()
verify()
encrypt()
decrypt()
digest() deriveBits()
deriveKey()
generateKey() wrapKey()
unwrapKey()
exportKey() importKey()
RSASSA PKCS1 v1.5
RSA PSS
RSA OAEP
ECDSA
ECDH
Ed255191
X255191
NODE ED255192
AES CTR
AES CBC
AES GCM
AES KW
HMAC
SHA 1
SHA 256
SHA 384
SHA 512
MD53
HKDF
PBKDF2

脚注:

  1. Secure Curves API で規定されたアルゴリズムです。

  2. レガシーの非標準 EdDSA は、Secure Curves 版に加えて、Ed25519 曲線向けにサポートされています。このアルゴリズムは非標準のため、利用時は次の点に注意してください。

    • アルゴリズムと namedCurve パラメーターには NODE-ED25519 を使います。
    • NodeJS と異なり、Cloudflare は秘密鍵の raw インポートをサポートしません。
    • アルゴリズムの実装は、時間とともに変わることがあります。現時点では保証できませんが、Cloudflare は後方互換性と NodeJS の挙動との互換性の維持に努めます。特筆すべき互換性の注意は、リリースノートとこの開発者ドキュメントで伝えます。
  3. MD5 は WebCrypto 標準の一部ではありませんが、MD5 を必要とするレガシーシステムと連携するために Cloudflare Workers でサポートしています。MD5 は弱いアルゴリズムと見なされます。セキュリティを MD5 に依存しないでください。


関連リソース

役に立ちましたか?