ウェブ暗号
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)ダイジェストストリーム- ストリーミングデータからハッシュダイジェストを生成することをサポートする
cryptoAPIへの非標準拡張です。DigestStream自体は、書き込まれたデータを保持しないWritableStreamです。代わりに、データの流れが終了したときに自動的にハッシュダイジェストを生成します。
- ストリーミングデータからハッシュダイジェストを生成することをサポートする
-
algorithmstring | object- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
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; }}export default { async fetch(req): Promise<Response> { // オリジンから取得 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; }} 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でなければなりません。
これらのメソッドはすべてcrypto.subtle ↗を介してアクセスされ、MDNで詳細に文書化されています。
-
encrypt(algorithm, key, data): Promise<ArrayBuffer>- パラメータとして与えられた平文、アルゴリズム、およびキーに対応する暗号化データで満たされるPromiseを返します。
-
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
keyCryptoKey -
dataBufferSource
-
decrypt(algorithm, key, data): Promise<ArrayBuffer>- パラメータとして与えられた暗号文、アルゴリズム、およびキーに対応する平文で満たされるPromiseを返します。
-
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
keyCryptoKey -
dataBufferSource
-
sign(algorithm, key, data): Promise<ArrayBuffer>- パラメータとして与えられたテキスト、アルゴリズム、およびキーに対応する署名で満たされるPromiseを返します。
-
algorithmstring | object- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
keyCryptoKey -
dataArrayBuffer
-
verify(algorithm, key, signature, data): Promise<boolean>- パラメータとして与えられた署名が、与えられたテキスト、アルゴリズム、およびキーと一致するかどうかを示すBoolean値で満たされるPromiseを返します。
-
algorithmstring | object- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
keyCryptoKey -
signatureArrayBuffer -
dataArrayBuffer
-
digest(algorithm, data): Promise<ArrayBuffer>- パラメータとして与えられたアルゴリズムとテキストから生成されたダイジェストで満たされるPromiseを返します。
-
algorithmstring | object- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
dataArrayBuffer
-
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']); - 対称アルゴリズム用の新しく生成された
-
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
extractablebool -
keyUsagesArray- 新しいキーの可能な使用法 ↗を示す文字列の配列です。
-
deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages): Promise<CryptoKey>- パラメータとして与えられたベースキーと特定のアルゴリズムから導出された新しく生成された
CryptoKeyで満たされるPromiseを返します。
- パラメータとして与えられたベースキーと特定のアルゴリズムから導出された新しく生成された
-
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
baseKeyCryptoKey -
derivedKeyAlgorithmobject- 導出されたキーが使用されるアルゴリズムをアルゴリズム特有の形式 ↗で定義します。
-
extractablebool -
keyUsagesArray- 新しいキーの可能な使用法 ↗を示す文字列の配列です。
-
deriveBits(algorithm, baseKey, length): Promise<ArrayBuffer>- パラメータとして与えられたベースキーと特定のアルゴリズムから導出された新しく生成された擬似ランダムビットのバッファで満たされるPromiseを返します。これは、導出されたビットを含む
ArrayBufferで満たされるPromiseを返します。このメソッドはderiveKey()に非常に似ていますが、deriveKey()はArrayBufferではなくCryptoKeyオブジェクトを返します。基本的に、deriveKey()はderiveBits()の後にimportKey()を組み合わせたものです。
- パラメータとして与えられたベースキーと特定のアルゴリズムから導出された新しく生成された擬似ランダムビットのバッファで満たされるPromiseを返します。これは、導出されたビットを含む
-
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
baseKeyCryptoKey -
lengthint- 導出するビット列の長さ。
-
importKey(format, keyData, algorithm, extractable, keyUsages): Promise<CryptoKey>- 外部のポータブル形式からWeb Crypto APIで使用するための
CryptoKeyに変換します。
- 外部のポータブル形式からWeb Crypto APIで使用するための
-
formatstring- インポートするキーの形式 ↗を記述します。
-
keyDataArrayBuffer -
algorithmobject- 使用するアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
extractablebool -
keyUsagesArray- 新しいキーの可能な使用法 ↗を示す文字列の配列です。
-
exportKey(formatstring, keyCryptoKey): Promise<ArrayBuffer>CryptoKeyがextractableである場合、ポータブル形式に変換します。
-
formatstring- エクスポートされるキーの形式 ↗を記述します。
-
keyCryptoKey
-
wrapKey(format, key, wrappingKey, wrapAlgo): Promise<ArrayBuffer>CryptoKeyをポータブル形式に変換し、別のキーで暗号化します。これにより、CryptoKeyは信頼できない環境での保存や送信に適したものになります。
-
formatstring- 暗号化される前にエクスポートされるキーの形式 ↗を記述します。
-
keyCryptoKey -
wrappingKeyCryptoKey -
wrapAlgoobject- エクスポートされたキーを暗号化するために使用されるアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
unwrapKey(format, key, unwrappingKey, unwrapAlgo,: Promise<CryptoKey>
unwrappedKeyAlgo, extractable, keyUsages)wrapKey()によってラップされたキーをCryptoKeyに戻します。
-
formatstring- アンラップされるキーのデータ形式 ↗を記述します。
-
keyCryptoKey -
unwrappingKeyCryptoKey -
unwrapAlgoobject- ラップされたキーを暗号化するために使用されたアルゴリズムを、アルゴリズム特有の形式 ↗で記述します。
-
unwrappedKeyAlgoobject- アンラップされるキーをアルゴリズム特有の形式 ↗で記述します。
-
extractablebool -
keyUsagesArray- 新しいキーの可能な使用法 ↗を示す文字列の配列です。
-
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 | ✓ | ✓ |
脚注:
-
Secure Curves API ↗に指定されたアルゴリズム。
-
レガシー非標準のEdDSAは、Secure Curvesバージョンに加えてEd25519曲線のためにサポートされています。このアルゴリズムは非標準であるため、使用する際には以下に注意してください:
NODE-ED25519をアルゴリズムおよびnamedCurveパラメータとして使用してください。- NodeJSとは異なり、Cloudflareはプライベートキーの生のインポートをサポートしません。
- アルゴリズムの実装は時間とともに変わる可能性があります。Cloudflareは現時点で保証できませんが、後方互換性とNodeJSの動作との互換性を維持するよう努めます。重要な互換性に関する注意事項は、リリースノートおよびこの開発者ドキュメントを通じて通知されます。
-
MD5はWebCrypto標準の一部ではありませんが、MD5を必要とするレガシーシステムとの相互作用のためにCloudflare Workersでサポートされています。MD5は弱いアルゴリズムと見なされています。セキュリティのためにMD5に依存しないでください。