コンテンツにスキップ

ウェブ暗号

背景

Web Crypto APIは、一般的な暗号タスクのための低レベル関数のセットを提供します。Workersランタイムは、このAPIの全機能を実装していますが、ほとんどのブラウザで実装されているものとはサポートされているアルゴリズムにいくつかの違いがあります。

Web Crypto APIを使用して暗号操作を行うことは、純粋にJavaScriptで行うよりも大幅に高速です。CPU集約型の暗号操作を行いたい場合は、Web Crypto APIの使用を検討すべきです。

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

const myText = new TextEncoder().encode('Hello world!');
const myDigest = await crypto.subtle.digest(
{
name: 'SHA-256',
},
myText // ハッシュ化したいデータ(ArrayBufferとして)
);
console.log(new Uint8Array(myDigest));

一般的な使用例にはリクエストの署名が含まれます。


コンストラクタ

  • crypto.DigestStream(algorithm) ダイジェストストリーム

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

パラメータ

使用法

export default {
async fetch(req) {
// オリジンから取得
const res = await fetch(req);
// ボディを2回読み取る必要があるため、`tee`します(2つのインスタンスを取得)
const [bodyOne, bodyTwo] = res.body.tee();
// ヘッダーを設定できるように新しいレスポンスを作成します(`fetch`からのレスポンスは不変です)
const newRes = new Response(bodyOne, res);
// SHA-256ダイジェストストリームを作成し、ボディをそれにパイプします
const digestStream = new crypto.DigestStream("SHA-256");
bodyTwo.pipeTo(digestStream);
// 最終結果を取得
const digest = await digestStream.digest;
// それを16進数の文字列に変換
const hexString = [...new Uint8Array(digest)]
.map(b => b.toString(16).padStart(2, '0'))
.join('')
// SHA-256ハッシュを持つヘッダーを設定し、レスポンスを返します
newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
return newRes;
}
}

メソッド

  • 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を返します。

パラメータ

digest

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

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

パラメータ

generateKey

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

    • 対称アルゴリズム用の新しく生成されたCryptoKey、または非対称アルゴリズム用の2つの新しく生成されたキーを含むCryptoKeyPairで満たされるPromiseを返します。たとえば、新しい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で満たされるPromiseを返します。このメソッドはderiveKey()に非常に似ていますが、deriveKey()ArrayBufferではなくCryptoKeyオブジェクトを返します。基本的に、deriveKey()deriveBits()の後にimportKey()を組み合わせたものです。

パラメータ

importKey

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

    • 外部のポータブル形式からWeb Crypto APIで使用するためのCryptoKeyに変換します。

パラメータ

exportKey

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

    • CryptoKeyextractableである場合、ポータブル形式に変換します。

パラメータ

  • formatstring

    • エクスポートされるキーの形式を記述します。
  • keyCryptoKey

wrapKey

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

    • CryptoKeyをポータブル形式に変換し、別のキーで暗号化します。これにより、CryptoKeyは信頼できない環境での保存や送信に適したものになります。

パラメータ

  • formatstring

    • 暗号化される前にエクスポートされるキーの形式を記述します。
  • keyCryptoKey

  • wrappingKeyCryptoKey

  • wrapAlgoobject

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曲線のためにサポートされています。このアルゴリズムは非標準であるため、使用する際には以下に注意してください:

    • NODE-ED25519をアルゴリズムおよびnamedCurveパラメータとして使用してください。
    • NodeJSとは異なり、Cloudflareはプライベートキーの生のインポートをサポートしません。
    • アルゴリズムの実装は時間とともに変わる可能性があります。Cloudflareは現時点で保証できませんが、後方互換性とNodeJSの動作との互換性を維持するよう努めます。重要な互換性に関する注意事項は、リリースノートおよびこの開発者ドキュメントを通じて通知されます。
  3. MD5はWebCrypto標準の一部ではありませんが、MD5を必要とするレガシーシステムとの相互作用のためにCloudflare Workersでサポートされています。MD5は弱いアルゴリズムと見なされています。セキュリティのためにMD5に依存しないでください。


関連リソース