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- ストリーミングデータからハッシュダイジェストを生成できる、
cryptoAPI の非標準拡張です。DigestStream自体はWritableStreamであり、書き込まれたデータは保持しません。代わりに、データの流れが終わったときに、自動でハッシュダイジェストを生成します。
- ストリーミングデータからハッシュダイジェストを生成できる、
-
algorithmstring | object- 使うアルゴリズムと、必要なパラメーターを、アルゴリズム固有の形式 ↗ で記述します。
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 である必要があります。
これらのメソッドは、すべて 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を含む Promise を返します。非対称アルゴリズムでは、新しく生成した 2 つのキーを含むCryptoKeyPairを返します。たとえば、新しい 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になります。このメソッドは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を移植可能な形式に変換し、別のキーで暗号化します。これにより、信頼できない環境での保存や転送に適した形になります。
-
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 曲線向けにサポートされています。このアルゴリズムは非標準のため、利用時は次の点に注意してください。
- アルゴリズムと
namedCurveパラメーターにはNODE-ED25519を使います。 - NodeJS と異なり、Cloudflare は秘密鍵の raw インポートをサポートしません。
- アルゴリズムの実装は、時間とともに変わることがあります。現時点では保証できませんが、Cloudflare は後方互換性と NodeJS の挙動との互換性の維持に努めます。特筆すべき互換性の注意は、リリースノートとこの開発者ドキュメントで伝えます。
- アルゴリズムと
-
MD5 は WebCrypto 標準の一部ではありませんが、MD5 を必要とするレガシーシステムと連携するために Cloudflare Workers でサポートしています。MD5 は弱いアルゴリズムと見なされます。セキュリティを MD5 に依存しないでください。