Node.js v25.0.0 文件
- Node.js v25.0.0
-
目錄
- Web Crypto API
- Web Cryptography API 中的現代演算法
- Web Cryptography API 中的安全曲線
- 示例
- 演算法矩陣
- 類:
Crypto - 類:
CryptoKey - 類:
CryptoKeyPair - 類:
SubtleCrypto- 靜態方法:
SubtleCrypto.supports(operation, algorithm[, lengthOrAdditionalAlgorithm]) subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)subtle.decrypt(algorithm, key, data)subtle.deriveBits(algorithm, baseKey[, length])subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)subtle.digest(algorithm, data)subtle.encapsulateBits(encapsulationAlgorithm, encapsulationKey)subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages)subtle.encrypt(algorithm, key, data)subtle.exportKey(format, key)subtle.getPublicKey(key, keyUsages)subtle.generateKey(algorithm, extractable, keyUsages)subtle.importKey(format, keyData, algorithm, extractable, keyUsages)subtle.sign(algorithm, key, data)subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)subtle.verify(algorithm, key, signature, data)subtle.wrapKey(format, key, wrappingKey, wrapAlgo)
- 靜態方法:
- 演算法引數
- 類:
Algorithm - 類:
AeadParams - 類:
AesDerivedKeyParams - 類:
AesCbcParams - 類:
AesCtrParams - 類:
AesKeyAlgorithm - 類:
AesKeyGenParams - 類:
Argon2Params - 類:
ContextParams - 類:
CShakeParams - 類:
EcdhKeyDeriveParams - 類:
EcdsaParams - 類:
EcKeyAlgorithm - 類:
EcKeyGenParams - 類:
EcKeyImportParams - 類:
EncapsulatedBits - 類:
EncapsulatedKey - 類:
HkdfParams - 類:
HmacImportParams - 類:
HmacKeyAlgorithm - 類:
HmacKeyGenParams - 類:
KeyAlgorithm - 類:
KmacImportParams - 類:
KmacKeyAlgorithm - 類:
KmacKeyGenParams - 類:
KmacParams - 類:
Pbkdf2Params - 類:
RsaHashedImportParams - 類:
RsaHashedKeyAlgorithm - 類:
RsaHashedKeyGenParams - 類:
RsaOaepParams - 類:
RsaPssParams
- 類:
- Web Crypto API
-
索引
- 斷言測試
- 非同步上下文跟蹤
- 非同步鉤子
- 緩衝區
- C++ 外掛
- 使用 Node-API 的 C/C++ 外掛
- C++ 嵌入器 API
- 子程序
- 叢集
- 命令列選項
- 控制檯
- 加密
- 偵錯程式
- 已棄用的 API
- 診斷通道
- DNS
- 域
- 環境變數
- 錯誤
- 事件
- 檔案系統
- 全域性物件
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:moduleAPI - 模組:包
- 模組:TypeScript
- 網路
- 作業系統
- 路徑
- 效能鉤子
- 許可權
- 程序
- Punycode
- 查詢字串
- 逐行讀取
- REPL
- 報告
- 單一可執行檔案應用
- SQLite
- 流
- 字串解碼器
- 測試執行器
- 定時器
- TLS/SSL
- 跟蹤事件
- TTY
- UDP/資料報
- URL
- 實用工具
- V8
- 虛擬機器
- WASI
- Web Crypto API
- Web Streams API
- 工作執行緒
- Zlib
- 其他版本
- 選項
Web Crypto API#
Node.js 提供了 Web Crypto API 標準的實現。
使用 globalThis.crypto 或 require('node:crypto').webcrypto 來訪問此模組。
const { subtle } = globalThis.crypto;
(async function() {
const key = await subtle.generateKey({
name: 'HMAC',
hash: 'SHA-256',
length: 256,
}, true, ['sign', 'verify']);
const enc = new TextEncoder();
const message = enc.encode('I love cupcakes');
const digest = await subtle.sign({
name: 'HMAC',
}, key, message);
})();
Web Cryptography API 中的現代演算法#
Node.js 提供了 Web Cryptography API 中的現代演算法 WICG 提案中的以下功能的實現
演算法
'AES-OCB'1'Argon2d'2'Argon2i'2'Argon2id'2'ChaCha20-Poly1305''cSHAKE128''cSHAKE256''KMAC128'1'KMAC256'1'ML-DSA-44'3'ML-DSA-65'3'ML-DSA-87'3'ML-KEM-512'3'ML-KEM-768'3'ML-KEM-1024'3'SHA3-256''SHA3-384''SHA3-512'
金鑰格式
'raw-public''raw-secret''raw-seed'
方法
Web Cryptography API 中的安全曲線#
Node.js 提供了 Web Cryptography API 中的安全曲線 WICG 提案中的以下功能的實現
演算法
'Ed448''X448'
示例#
生成金鑰#
<SubtleCrypto> 類可用於生成對稱(私密)金鑰或非對稱金鑰對(公鑰和私鑰)。
AES 金鑰#
const { subtle } = globalThis.crypto;
async function generateAesKey(length = 256) {
const key = await subtle.generateKey({
name: 'AES-CBC',
length,
}, true, ['encrypt', 'decrypt']);
return key;
}
ECDSA 金鑰對#
const { subtle } = globalThis.crypto;
async function generateEcKey(namedCurve = 'P-521') {
const {
publicKey,
privateKey,
} = await subtle.generateKey({
name: 'ECDSA',
namedCurve,
}, true, ['sign', 'verify']);
return { publicKey, privateKey };
}
Ed25519/X25519 金鑰對#
const { subtle } = globalThis.crypto;
async function generateEd25519Key() {
return subtle.generateKey({
name: 'Ed25519',
}, true, ['sign', 'verify']);
}
async function generateX25519Key() {
return subtle.generateKey({
name: 'X25519',
}, true, ['deriveKey']);
}
HMAC 金鑰#
const { subtle } = globalThis.crypto;
async function generateHmacKey(hash = 'SHA-256') {
const key = await subtle.generateKey({
name: 'HMAC',
hash,
}, true, ['sign', 'verify']);
return key;
}
RSA 金鑰對#
const { subtle } = globalThis.crypto;
const publicExponent = new Uint8Array([1, 0, 1]);
async function generateRsaKey(modulusLength = 2048, hash = 'SHA-256') {
const {
publicKey,
privateKey,
} = await subtle.generateKey({
name: 'RSASSA-PKCS1-v1_5',
modulusLength,
publicExponent,
hash,
}, true, ['sign', 'verify']);
return { publicKey, privateKey };
}
加密和解密#
const crypto = globalThis.crypto;
async function aesEncrypt(plaintext) {
const ec = new TextEncoder();
const key = await generateAesKey();
const iv = crypto.getRandomValues(new Uint8Array(16));
const ciphertext = await crypto.subtle.encrypt({
name: 'AES-CBC',
iv,
}, key, ec.encode(plaintext));
return {
key,
iv,
ciphertext,
};
}
async function aesDecrypt(ciphertext, key, iv) {
const dec = new TextDecoder();
const plaintext = await crypto.subtle.decrypt({
name: 'AES-CBC',
iv,
}, key, ciphertext);
return dec.decode(plaintext);
}
匯出和匯入金鑰#
const { subtle } = globalThis.crypto;
async function generateAndExportHmacKey(format = 'jwk', hash = 'SHA-512') {
const key = await subtle.generateKey({
name: 'HMAC',
hash,
}, true, ['sign', 'verify']);
return subtle.exportKey(format, key);
}
async function importHmacKey(keyData, format = 'jwk', hash = 'SHA-512') {
const key = await subtle.importKey(format, keyData, {
name: 'HMAC',
hash,
}, true, ['sign', 'verify']);
return key;
}
包裝和解包金鑰#
const { subtle } = globalThis.crypto;
async function generateAndWrapHmacKey(format = 'jwk', hash = 'SHA-512') {
const [
key,
wrappingKey,
] = await Promise.all([
subtle.generateKey({
name: 'HMAC', hash,
}, true, ['sign', 'verify']),
subtle.generateKey({
name: 'AES-KW',
length: 256,
}, true, ['wrapKey', 'unwrapKey']),
]);
const wrappedKey = await subtle.wrapKey(format, key, wrappingKey, 'AES-KW');
return { wrappedKey, wrappingKey };
}
async function unwrapHmacKey(
wrappedKey,
wrappingKey,
format = 'jwk',
hash = 'SHA-512') {
const key = await subtle.unwrapKey(
format,
wrappedKey,
wrappingKey,
'AES-KW',
{ name: 'HMAC', hash },
true,
['sign', 'verify']);
return key;
}
簽名和驗證#
const { subtle } = globalThis.crypto;
async function sign(key, data) {
const ec = new TextEncoder();
const signature =
await subtle.sign('RSASSA-PKCS1-v1_5', key, ec.encode(data));
return signature;
}
async function verify(key, signature, data) {
const ec = new TextEncoder();
const verified =
await subtle.verify(
'RSASSA-PKCS1-v1_5',
key,
signature,
ec.encode(data));
return verified;
}
派生位元和金鑰#
const { subtle } = globalThis.crypto;
async function pbkdf2(pass, salt, iterations = 1000, length = 256) {
const ec = new TextEncoder();
const key = await subtle.importKey(
'raw',
ec.encode(pass),
'PBKDF2',
false,
['deriveBits']);
const bits = await subtle.deriveBits({
name: 'PBKDF2',
hash: 'SHA-512',
salt: ec.encode(salt),
iterations,
}, key, length);
return bits;
}
async function pbkdf2Key(pass, salt, iterations = 1000, length = 256) {
const ec = new TextEncoder();
const keyMaterial = await subtle.importKey(
'raw',
ec.encode(pass),
'PBKDF2',
false,
['deriveKey']);
const key = await subtle.deriveKey({
name: 'PBKDF2',
hash: 'SHA-512',
salt: ec.encode(salt),
iterations,
}, keyMaterial, {
name: 'AES-GCM',
length,
}, true, ['encrypt', 'decrypt']);
return key;
}
摘要#
const { subtle } = globalThis.crypto;
async function digest(data, algorithm = 'SHA-512') {
const ec = new TextEncoder();
const digest = await subtle.digest(algorithm, ec.encode(data));
return digest;
}
檢查執行時演算法支援#
SubtleCrypto.supports() 允許在 Web Crypto API 中進行特性檢測,可用於檢測給定的演算法識別符號(包括其引數)是否支援給定的操作。
此示例演示瞭如果可用,則使用 Argon2 從密碼派生金鑰,否則使用 PBKDF2;然後如果可用,則使用 AES-OCB 加密和解密一些文字,否則使用 AES-GCM。
const { SubtleCrypto, crypto } = globalThis;
const password = 'correct horse battery staple';
const derivationAlg =
SubtleCrypto.supports?.('importKey', 'Argon2id') ?
'Argon2id' :
'PBKDF2';
const encryptionAlg =
SubtleCrypto.supports?.('importKey', 'AES-OCB') ?
'AES-OCB' :
'AES-GCM';
const passwordKey = await crypto.subtle.importKey(
derivationAlg === 'Argon2id' ? 'raw-secret' : 'raw',
new TextEncoder().encode(password),
derivationAlg,
false,
['deriveKey'],
);
const nonce = crypto.getRandomValues(new Uint8Array(16));
const derivationParams =
derivationAlg === 'Argon2id' ?
{
nonce,
parallelism: 4,
memory: 2 ** 21,
passes: 1,
} :
{
salt: nonce,
iterations: 100_000,
hash: 'SHA-256',
};
const key = await crypto.subtle.deriveKey(
{
name: derivationAlg,
...derivationParams,
},
passwordKey,
{
name: encryptionAlg,
length: 256,
},
false,
['encrypt', 'decrypt'],
);
const plaintext = 'Hello, world!';
const iv = crypto.getRandomValues(new Uint8Array(16));
const encrypted = await crypto.subtle.encrypt(
{ name: encryptionAlg, iv },
key,
new TextEncoder().encode(plaintext),
);
const decrypted = new TextDecoder().decode(await crypto.subtle.decrypt(
{ name: encryptionAlg, iv },
key,
encrypted,
));
演算法矩陣#
下表詳細說明了 Node.js Web Crypto API 實現支援的演算法以及每個演算法支援的 API。
金鑰管理 API#
| 演算法 | subtle.generateKey() | subtle.exportKey() | subtle.importKey() | subtle.getPublicKey() |
|---|---|---|---|---|
'AES-CBC' | ✔ | ✔ | ✔ | |
'AES-CTR' | ✔ | ✔ | ✔ | |
'AES-GCM' | ✔ | ✔ | ✔ | |
'AES-KW' | ✔ | ✔ | ✔ | |
'AES-OCB' | ✔ | ✔ | ✔ | |
'Argon2d' | ✔ | |||
'Argon2i' | ✔ | |||
'Argon2id' | ✔ | |||
'ChaCha20-Poly1305'4 | ✔ | ✔ | ✔ | |
'ECDH' | ✔ | ✔ | ✔ | ✔ |
'ECDSA' | ✔ | ✔ | ✔ | ✔ |
'Ed25519' | ✔ | ✔ | ✔ | ✔ |
'Ed448'5 | ✔ | ✔ | ✔ | ✔ |
'HKDF' | ✔ | |||
'HMAC' | ✔ | ✔ | ✔ | |
'KMAC128'4 | ✔ | ✔ | ✔ | |
'KMAC256'4 | ✔ | ✔ | ✔ | |
'ML-DSA-44'4 | ✔ | ✔ | ✔ | ✔ |
'ML-DSA-65'4 | ✔ | ✔ | ✔ | ✔ |
'ML-DSA-87'4 | ✔ | ✔ | ✔ | ✔ |
'ML-KEM-512'4 | ✔ | ✔ | ✔ | ✔ |
'ML-KEM-768'4 | ✔ | ✔ | ✔ | ✔ |
'ML-KEM-1024'4 | ✔ | ✔ | ✔ | ✔ |
'PBKDF2' | ✔ | |||
'RSA-OAEP' | ✔ | ✔ | ✔ | ✔ |
'RSA-PSS' | ✔ | ✔ | ✔ | ✔ |
'RSASSA-PKCS1-v1_5' | ✔ | ✔ | ✔ | ✔ |
'X25519' | ✔ | ✔ | ✔ | ✔ |
'X448'5 | ✔ | ✔ | ✔ | ✔ |
加密操作 API#
列圖例
- 加密:
subtle.encrypt()/subtle.decrypt() - 簽名和 MAC:
subtle.sign()/subtle.verify() - 金鑰或位元派生:
subtle.deriveBits()/subtle.deriveKey() - 金鑰包裝:
subtle.wrapKey()/subtle.unwrapKey() - 金鑰封裝:
subtle.encapsulateBits()/subtle.decapsulateBits()/subtle.encapsulateKey()/subtle.decapsulateKey() - 摘要:
subtle.digest()
| 演算法 | 加密 | 簽名和 MAC | 金鑰或位元派生 | 金鑰包裝 | 金鑰封裝 | 摘要 |
|---|---|---|---|---|---|---|
'AES-CBC' | ✔ | ✔ | ||||
'AES-CTR' | ✔ | ✔ | ||||
'AES-GCM' | ✔ | ✔ | ||||
'AES-KW' | ✔ | |||||
'AES-OCB' | ✔ | ✔ | ||||
'Argon2d' | ✔ | |||||
'Argon2i' | ✔ | |||||
'Argon2id' | ✔ | |||||
'ChaCha20-Poly1305'4 | ✔ | ✔ | ||||
'cSHAKE128'4 | ✔ | |||||
'cSHAKE256'4 | ✔ | |||||
'ECDH' | ✔ | |||||
'ECDSA' | ✔ | |||||
'Ed25519' | ✔ | |||||
'Ed448'5 | ✔ | |||||
'HKDF' | ✔ | |||||
'HMAC' | ✔ | |||||
'KMAC128'4 | ✔ | |||||
'KMAC256'4 | ✔ | |||||
'ML-DSA-44'4 | ✔ | |||||
'ML-DSA-65'4 | ✔ | |||||
'ML-DSA-87'4 | ✔ | |||||
'ML-KEM-512'4 | ✔ | |||||
'ML-KEM-768'4 | ✔ | |||||
'ML-KEM-1024'4 | ✔ | |||||
'PBKDF2' | ✔ | |||||
'RSA-OAEP' | ✔ | ✔ | ||||
'RSA-PSS' | ✔ | |||||
'RSASSA-PKCS1-v1_5' | ✔ | |||||
'SHA-1' | ✔ | |||||
'SHA-256' | ✔ | |||||
'SHA-384' | ✔ | |||||
'SHA-512' | ✔ | |||||
'SHA3-256'4 | ✔ | |||||
'SHA3-384'4 | ✔ | |||||
'SHA3-512'4 | ✔ | |||||
'X25519' | ✔ | |||||
'X448'5 | ✔ |
類:Crypto#
globalThis.crypto 是 Crypto 類的例項。Crypto 是一個單例,提供對加密 API 其餘部分的訪問。
crypto.getRandomValues(typedArray)#
typedArray<Buffer> | <TypedArray>- 返回:<Buffer> | <TypedArray>
生成加密強度高的隨機值。給定的 typedArray 會被隨機值填充,並返回對 typedArray 的引用。
給定的 typedArray 必須是基於整數的 <TypedArray> 例項,即不接受 Float32Array 和 Float64Array。
如果給定的 typedArray 大於 65,536 位元組,將會丟擲錯誤。
類:CryptoKey#
cryptoKey.algorithm#
- 型別:<KeyAlgorithm> | <RsaHashedKeyAlgorithm> | <EcKeyAlgorithm> | <AesKeyAlgorithm> | <HmacKeyAlgorithm> | <KmacKeyAlgorithm>
一個物件,詳細說明了該金鑰可用於的演算法以及其他特定於演算法的引數。
只讀。
cryptoKey.extractable#
- 型別:<boolean>
當為 true 時,<CryptoKey> 可以使用 subtle.exportKey() 或 subtle.wrapKey() 提取。
只讀。
cryptoKey.type#
- 型別:<string>
'secret'、'private'或'public'之一。
一個字串,標識該金鑰是 symmetric ('secret') 還是 asymmetric ('private' 或 'public') 金鑰。
cryptoKey.usages#
- 型別:<string[]>
一個字串陣列,標識了金鑰可用於的操作。
可能的用法有
'encrypt'- 允許使用金鑰與subtle.encrypt()'decrypt'- 允許使用金鑰與subtle.decrypt()'sign'- 允許使用金鑰與subtle.sign()'verify'- 允許使用金鑰與subtle.verify()'deriveKey'- 允許使用金鑰與subtle.deriveKey()'deriveBits'- 允許使用金鑰與subtle.deriveBits()'encapsulateBits'- 允許使用金鑰與subtle.encapsulateBits()'decapsulateBits'- 允許使用金鑰與subtle.decapsulateBits()'encapsulateKey'- 允許使用金鑰與subtle.encapsulateKey()'decapsulateKey'- 允許使用金鑰與subtle.decapsulateKey()'wrapKey'- 允許使用金鑰與subtle.wrapKey()'unwrapKey'- 允許使用金鑰與subtle.unwrapKey()
有效的金鑰用法取決於金鑰演算法(由 cryptokey.algorithm.name 標識)。
列圖例
- 加密:
subtle.encrypt()/subtle.decrypt() - 簽名和 MAC:
subtle.sign()/subtle.verify() - 金鑰或位元派生:
subtle.deriveBits()/subtle.deriveKey() - 金鑰包裝:
subtle.wrapKey()/subtle.unwrapKey() - 金鑰封裝:
subtle.encapsulateBits()/subtle.decapsulateBits()/subtle.encapsulateKey()/subtle.decapsulateKey()
| 支援的金鑰演算法 | 加密 | 簽名和 MAC | 金鑰或位元派生 | 金鑰包裝 | 金鑰封裝 |
|---|---|---|---|---|---|
'AES-CBC' | ✔ | ✔ | |||
'AES-CTR' | ✔ | ✔ | |||
'AES-GCM' | ✔ | ✔ | |||
'AES-KW' | ✔ | ||||
'AES-OCB' | ✔ | ✔ | |||
'Argon2d' | ✔ | ||||
'Argon2i' | ✔ | ||||
'Argon2id' | ✔ | ||||
'ChaCha20-Poly1305'4 | ✔ | ✔ | |||
'ECDH' | ✔ | ||||
'ECDSA' | ✔ | ||||
'Ed25519' | ✔ | ||||
'Ed448'5 | ✔ | ||||
'HDKF' | ✔ | ||||
'HMAC' | ✔ | ||||
'KMAC128'4 | ✔ | ||||
'KMAC256'4 | ✔ | ||||
'ML-DSA-44'4 | ✔ | ||||
'ML-DSA-65'4 | ✔ | ||||
'ML-DSA-87'4 | ✔ | ||||
'ML-KEM-512'4 | ✔ | ||||
'ML-KEM-768'4 | ✔ | ||||
'ML-KEM-1024'4 | ✔ | ||||
'PBKDF2' | ✔ | ||||
'RSA-OAEP' | ✔ | ✔ | |||
'RSA-PSS' | ✔ | ||||
'RSASSA-PKCS1-v1_5' | ✔ | ||||
'X25519' | ✔ | ||||
'X448'5 | ✔ |
類:CryptoKeyPair#
CryptoKeyPair 是一個簡單的字典物件,具有 publicKey 和 privateKey 屬性,代表一個非對稱金鑰對。
cryptoKeyPair.privateKey#
- 型別:<CryptoKey> 一個 <CryptoKey>,其
type將為'private'。
cryptoKeyPair.publicKey#
- 型別:<CryptoKey> 一個 <CryptoKey>,其
type將為'public'。
類:SubtleCrypto#
靜態方法:SubtleCrypto.supports(operation, algorithm[, lengthOrAdditionalAlgorithm])#
operation<string> "encrypt"、"decrypt"、"sign"、"verify"、"digest"、"generateKey"、"deriveKey"、"deriveBits"、"importKey"、"exportKey"、"getPublicKey"、"wrapKey"、"unwrapKey"、"encapsulateBits"、"encapsulateKey"、"decapsulateBits" 或 "decapsulateKey"algorithm<string> | <Algorithm>lengthOrAdditionalAlgorithm<null> | <number> | <string> | <Algorithm> | <undefined> 根據操作的不同,此引數可能被忽略,或者當操作為 "deriveBits" 時是 length 引數的值,當操作為 "deriveKey" 時是待派生金鑰的演算法,當操作為 "wrapKey" 時是包裝前待匯出金鑰的演算法,當操作為 "unwrapKey" 時是解包後待匯入金鑰的演算法,或者當操作為 "encapsulateKey" 或 "decapsulateKey" 時是金鑰封裝/解封裝後待匯入金鑰的演算法。預設值:當操作為 "deriveBits" 時為null,否則為undefined。- 返回:<boolean> 指示實現是否支援給定的操作
允許在 Web Crypto API 中進行特性檢測,可用於檢測給定的演算法識別符號(包括其引數)是否支援給定的操作。
有關此方法的示例用法,請參閱檢查執行時演算法支援。
subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)#
decapsulationAlgorithm<string> | <Algorithm>decapsulationKey<CryptoKey>ciphertext<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為 <ArrayBuffer>。
訊息接收者使用其非對稱私鑰解密一個“封裝的金鑰”(密文),從而恢復一個臨時的對稱金鑰(表示為 <ArrayBuffer>),然後用該金鑰解密訊息。
當前支援的演算法包括
subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)#
decapsulationAlgorithm<string> | <Algorithm>decapsulationKey<CryptoKey>ciphertext<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>sharedKeyAlgorithm<string> | <Algorithm> | <HmacImportParams> | <AesDerivedKeyParams> | <KmacImportParams>extractable<boolean>usages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為 <CryptoKey>。
訊息接收者使用其非對稱私鑰解密一個“封裝的金鑰”(密文),從而恢復一個臨時的對稱金鑰(表示為 <CryptoKey>),然後用該金鑰解密訊息。
當前支援的演算法包括
subtle.decrypt(algorithm, key, data)#
algorithm<RsaOaepParams> | <AesCtrParams> | <AesCbcParams> | <AeadParams>key<CryptoKey>data<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
使用 algorithm 中指定的方法和引數以及 key 提供的金鑰材料,此方法嘗試解密提供的 data。如果成功,返回的 promise 將以包含明文結果的 <ArrayBuffer> 來解決。
當前支援的演算法包括
subtle.deriveBits(algorithm, baseKey[, length])#
algorithm<EcdhKeyDeriveParams> | <HkdfParams> | <Pbkdf2Params> | <Argon2Params>baseKey<CryptoKey>length<number> | <null> 預設值:null- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
使用 algorithm 中指定的方法和引數以及 baseKey 提供的金鑰材料,此方法嘗試生成 length 個位元。
當未提供 length 或為 null 時,將生成給定演算法的最大位元數。這對於 'ECDH'、'X25519' 和 'X448'5 演算法是允許的,對於其他演算法,length 必須是數字。
如果成功,返回的 promise 將以包含生成資料的 <ArrayBuffer> 來解決。
當前支援的演算法包括
subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)#
algorithm<EcdhKeyDeriveParams> | <HkdfParams> | <Pbkdf2Params> | <Argon2Params>baseKey<CryptoKey>derivedKeyAlgorithm<string> | <Algorithm> | <HmacImportParams> | <AesDerivedKeyParams> | <KmacImportParams>extractable<boolean>keyUsages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為一個 <CryptoKey>。
使用 algorithm 中指定的方法和引數,以及 baseKey 提供的金鑰材料,此方法嘗試根據 derivedKeyAlgorithm 中的方法和引數生成一個新的 <CryptoKey>。
呼叫此方法等同於呼叫 subtle.deriveBits() 來生成原始金鑰材料,然後將結果傳遞給 subtle.importKey() 方法,並使用 deriveKeyAlgorithm、extractable 和 keyUsages 引數作為輸入。
當前支援的演算法包括
subtle.digest(algorithm, data)#
algorithm<string> | <Algorithm> | <CShakeParams>data<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
使用 algorithm 標識的方法,此方法嘗試生成 data 的摘要。如果成功,返回的 promise 將以包含計算出的摘要的 <ArrayBuffer> 來解決。
如果 algorithm 以 <string> 形式提供,它必須是以下之一
如果 algorithm 以 <Object> 形式提供,它必須有一個 name 屬性,其值是上述之一。
subtle.encapsulateBits(encapsulationAlgorithm, encapsulationKey)#
encapsulationAlgorithm<string> | <Algorithm>encapsulationKey<CryptoKey>- 返回:<Promise> 成功時履行,值為 <EncapsulatedBits>。
使用訊息接收者的非對稱公鑰加密一個臨時的對稱金鑰。這個加密後的金鑰就是“封裝的金鑰”,表示為 <EncapsulatedBits>。
當前支援的演算法包括
subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages)#
encapsulationAlgorithm<string> | <Algorithm>encapsulationKey<CryptoKey>sharedKeyAlgorithm<string> | <Algorithm> | <HmacImportParams> | <AesDerivedKeyParams> | <KmacImportParams>extractable<boolean>usages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為 <EncapsulatedKey>。
使用訊息接收者的非對稱公鑰加密一個臨時的對稱金鑰。這個加密後的金鑰就是“封裝的金鑰”,表示為 <EncapsulatedKey>。
當前支援的演算法包括
subtle.encrypt(algorithm, key, data)#
algorithm<RsaOaepParams> | <AesCtrParams> | <AesCbcParams> | <AeadParams>key<CryptoKey>data<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
使用 algorithm 指定的方法和引數以及 key 提供的金鑰材料,此方法嘗試加密 data。如果成功,返回的 promise 將以包含加密結果的 <ArrayBuffer> 來解決。
當前支援的演算法包括
subtle.exportKey(format, key)#
format<string> 必須是'raw'、'pkcs8'、'spki'、'jwk'、'raw-secret'4、'raw-public'4 或'raw-seed'4 之一。key<CryptoKey>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer> | <Object>。
將給定的金鑰匯出為指定的格式(如果支援)。
如果 <CryptoKey> 不可提取,返回的 promise 將會拒絕。
當 format 是 'pkcs8' 或 'spki' 且匯出成功時,返回的 promise 將以包含匯出金鑰資料的 <ArrayBuffer> 來解決。
當 format 是 'jwk' 且匯出成功時,返回的 promise 將以一個符合 JSON Web Key 規範的 JavaScript 物件來解決。
| 支援的金鑰演算法 | 'spki' | 'pkcs8' | 'jwk' | 'raw' | 'raw-secret' | 'raw-public' | 'raw-seed' |
|---|---|---|---|---|---|---|---|
'AES-CBC' | ✔ | ✔ | ✔ | ||||
'AES-CTR' | ✔ | ✔ | ✔ | ||||
'AES-GCM' | ✔ | ✔ | ✔ | ||||
'AES-KW' | ✔ | ✔ | ✔ | ||||
'AES-OCB'4 | ✔ | ✔ | |||||
'ChaCha20-Poly1305'4 | ✔ | ✔ | |||||
'ECDH' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ECDSA' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'Ed25519' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'Ed448'5 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'HMAC' | ✔ | ✔ | ✔ | ||||
'KMAC128'4 | ✔ | ✔ | |||||
'KMAC256'4 | ✔ | ✔ | |||||
'ML-DSA-44'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-DSA-65'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-DSA-87'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-KEM-512'4 | ✔ | ✔ | ✔ | ✔ | |||
'ML-KEM-768'4 | ✔ | ✔ | ✔ | ✔ | |||
'ML-KEM-1024'4 | ✔ | ✔ | ✔ | ✔ | |||
'RSA-OAEP' | ✔ | ✔ | ✔ | ||||
'RSA-PSS' | ✔ | ✔ | ✔ | ||||
'RSASSA-PKCS1-v1_5' | ✔ | ✔ | ✔ |
subtle.getPublicKey(key, keyUsages)#
key<CryptoKey> 一個私鑰,用於派生對應的公鑰。keyUsages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為一個 <CryptoKey>。
從給定的私鑰派生公鑰。
subtle.generateKey(algorithm, extractable, keyUsages)#
algorithm<string> | <Algorithm> | <RsaHashedKeyGenParams> | <EcKeyGenParams> | <HmacKeyGenParams> | <AesKeyGenParams> | <KmacKeyGenParams>
extractable<boolean>keyUsages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為一個 <CryptoKey> | <CryptoKeyPair>。
使用 algorithm 中提供的引數,此方法嘗試生成新的金鑰材料。根據所用演算法的不同,會生成一個 <CryptoKey> 或一個 <CryptoKeyPair>。
支援的生成 <CryptoKeyPair>(公鑰和私鑰)的演算法包括
'ECDH''ECDSA''Ed25519''Ed448'5'ML-DSA-44'4'ML-DSA-65'4'ML-DSA-87'4'ML-KEM-512'4'ML-KEM-768'4'ML-KEM-1024'4'RSA-OAEP''RSA-PSS''RSASSA-PKCS1-v1_5''X25519''X448'5
支援的生成 <CryptoKey>(私密金鑰)的演算法包括
subtle.importKey(format, keyData, algorithm, extractable, keyUsages)#
format<string> 必須是'raw'、'pkcs8'、'spki'、'jwk'、'raw-secret'4、'raw-public'4 或'raw-seed'4 之一。keyData<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <Object>
algorithm<string> | <Algorithm> | <RsaHashedImportParams> | <EcKeyImportParams> | <HmacImportParams> | <KmacImportParams>
extractable<boolean>keyUsages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為一個 <CryptoKey>。
此方法嘗試將提供的 keyData 解釋為給定的 format,以使用提供的 algorithm、extractable 和 keyUsages 引數建立一個 <CryptoKey> 例項。如果匯入成功,返回的 promise 將以金鑰材料的 <CryptoKey> 表示來解決。
如果匯入 KDF 演算法金鑰,extractable 必須為 false。
當前支援的演算法包括
| 支援的金鑰演算法 | 'spki' | 'pkcs8' | 'jwk' | 'raw' | 'raw-secret' | 'raw-public' | 'raw-seed' |
|---|---|---|---|---|---|---|---|
'AES-CBC' | ✔ | ✔ | ✔ | ||||
'AES-CTR' | ✔ | ✔ | ✔ | ||||
'AES-GCM' | ✔ | ✔ | ✔ | ||||
'AES-KW' | ✔ | ✔ | ✔ | ||||
'AES-OCB'4 | ✔ | ✔ | |||||
'Argon2d'4 | ✔ | ||||||
'Argon2i'4 | ✔ | ||||||
'Argon2id'4 | ✔ | ||||||
'ChaCha20-Poly1305'4 | ✔ | ✔ | |||||
'ECDH' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ECDSA' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'Ed25519' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'Ed448'5 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'HDKF' | ✔ | ✔ | |||||
'HMAC' | ✔ | ✔ | ✔ | ||||
'KMAC128'4 | ✔ | ✔ | |||||
'KMAC256'4 | ✔ | ✔ | |||||
'ML-DSA-44'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-DSA-65'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-DSA-87'4 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'ML-KEM-512'4 | ✔ | ✔ | ✔ | ✔ | |||
'ML-KEM-768'4 | ✔ | ✔ | ✔ | ✔ | |||
'ML-KEM-1024'4 | ✔ | ✔ | ✔ | ✔ | |||
'PBKDF2' | ✔ | ✔ | |||||
'RSA-OAEP' | ✔ | ✔ | ✔ | ||||
'RSA-PSS' | ✔ | ✔ | ✔ | ||||
'RSASSA-PKCS1-v1_5' | ✔ | ✔ | ✔ | ||||
'X25519' | ✔ | ✔ | ✔ | ✔ | ✔ | ||
'X448'5 | ✔ | ✔ | ✔ | ✔ | ✔ |
subtle.sign(algorithm, key, data)#
algorithm<string> | <Algorithm> | <RsaPssParams> | <EcdsaParams> | <ContextParams> | <KmacParams>key<CryptoKey>data<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
使用 algorithm 給定的方法和引數以及 key 提供的金鑰材料,此方法嘗試生成 data 的加密簽名。如果成功,返回的 promise 將以包含生成簽名的 <ArrayBuffer> 來解決。
當前支援的演算法包括
subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)#
format<string> 必須是'raw'、'pkcs8'、'spki'、'jwk'、'raw-secret'4、'raw-public'4 或'raw-seed'4 之一。wrappedKey<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>unwrappingKey<CryptoKey>
unwrapAlgo<string> | <Algorithm> | <RsaOaepParams> | <AesCtrParams> | <AesCbcParams> | <AeadParams>unwrappedKeyAlgo<string> | <Algorithm> | <RsaHashedImportParams> | <EcKeyImportParams> | <HmacImportParams> | <KmacImportParams>
extractable<boolean>keyUsages<string[]> 參見金鑰用法。- 返回:<Promise> 成功時履行,值為一個 <CryptoKey>。
在密碼學中,“包裝金鑰”是指匯出然後加密金鑰材料。此方法嘗試解密一個包裝的金鑰並建立一個 <CryptoKey> 例項。它等同於首先對加密的金鑰資料呼叫 subtle.decrypt()(使用 wrappedKey、unwrapAlgo 和 unwrappingKey 引數作為輸入),然後將結果傳遞給 subtle.importKey() 方法,並使用 unwrappedKeyAlgo、extractable 和 keyUsages 引數作為輸入。如果成功,返回的 promise 將以一個 <CryptoKey> 物件來解決。
當前支援的包裝演算法包括
支援的解包金鑰演算法包括
subtle.verify(algorithm, key, signature, data)#
algorithm<string> | <Algorithm> | <RsaPssParams> | <EcdsaParams> | <ContextParams> | <KmacParams>key<CryptoKey>signature<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>data<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>- 返回:<Promise> 成功時履行,值為一個 <boolean>。
該方法使用 algorithm 中給定的方法和引數以及 key 提供的金鑰材料,嘗試驗證 signature 是否是 data 的有效加密簽名。返回的 Promise 將解析為 true 或 false。
當前支援的演算法包括
subtle.wrapKey(format, key, wrappingKey, wrapAlgo)#
format<string> 必須是'raw'、'pkcs8'、'spki'、'jwk'、'raw-secret'4、'raw-public'4 或'raw-seed'4 之一。key<CryptoKey>wrappingKey<CryptoKey>wrapAlgo<string> | <Algorithm> | <RsaOaepParams> | <AesCtrParams> | <AesCbcParams> | <AeadParams>- 返回:<Promise> 成功時履行,值為一個 <ArrayBuffer>。
在密碼學中,“包裝金鑰”指的是匯出金鑰材料然後對其進行加密。此方法將金鑰材料匯出為 format 標識的格式,然後使用 wrapAlgo 指定的方法和引數以及 wrappingKey 提供的金鑰材料對其進行加密。這相當於使用 format 和 key 作為引數呼叫 subtle.exportKey(),然後將結果傳遞給 subtle.encrypt() 方法,並使用 wrappingKey 和 wrapAlgo 作為輸入。如果成功,返回的 Promise 將解析為一個包含加密金鑰資料的 <ArrayBuffer>。
當前支援的包裝演算法包括
演算法引數#
演算法引數物件定義了各種 <SubtleCrypto> 方法所使用的方法和引數。雖然這裡描述為“類”,但它們是簡單的 JavaScript 字典物件。
類:AeadParams#
aeadParams.additionalData#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <undefined>
未加密但包含在資料認證中的額外輸入。additionalData 的使用是可選的。
類:AesDerivedKeyParams#
類:AesCbcParams#
aesCbcParams.iv#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>
提供初始化向量。其長度必須正好為 16 位元組,並且應該是不可預測且加密安全的隨機值。
類:AesCtrParams#
aesCtrParams.counter#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>
計數器塊的初始值。該值必須正好為 16 位元組長。
AES-CTR 方法使用塊的最右側 length 位作為計數器,其餘位作為 nonce。
類:AesKeyAlgorithm#
類:AesKeyGenParams#
類:Argon2Params#
類:ContextParams#
contextParams.context#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <undefined>
context 成員表示要與訊息關聯的可選上下文資料。
類:CShakeParams#
cShakeParams.customization#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <undefined>
customization 成員表示定製化字串。Node.js Web Crypto API 實現僅支援零長度的定製化,這等同於完全不提供定製化。
cShakeParams.functionName#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <undefined>
functionName 成員表示函式名,NIST 使用它來定義基於 cSHAKE 的函式。Node.js Web Crypto API 實現僅支援零長度的 functionName,這等同於完全不提供 functionName。
類:EcdhKeyDeriveParams#
ecdhKeyDeriveParams.public#
- 型別:<CryptoKey>
ECDH 金鑰派生的操作方式是,將一方的私鑰和另一方的公鑰作為輸入——使用兩者生成一個共同的共享金鑰。ecdhKeyDeriveParams.public 屬性被設定為另一方的公鑰。
類:EcdsaParams#
ecdsaParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
類:EcKeyGenParams#
類:EcKeyImportParams#
類:EncapsulatedBits#
一個用於訊息加密的臨時對稱金鑰(表示為 <ArrayBuffer>)和由該共享金鑰加密的密文(可與訊息一起傳輸給訊息接收者)。接收者使用其私鑰來確定共享金鑰是什麼,然後可以解密訊息。
encapsulatedBits.ciphertext#
encapsulatedBits.sharedKey#
類:EncapsulatedKey#
一個用於訊息加密的臨時對稱金鑰(表示為 <CryptoKey>)和由該共享金鑰加密的密文(可與訊息一起傳輸給訊息接收者)。接收者使用其私鑰來確定共享金鑰是什麼,然後可以解密訊息。
encapsulatedKey.ciphertext#
encapsulatedKey.sharedKey#
- 型別:<CryptoKey>
類:HkdfParams#
hkdfParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
hkdfParams.info#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>
為 HKDF 演算法提供特定於應用程式的上下文輸入。此輸入可以為零長度,但必須提供。
hkdfParams.salt#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>
鹽值顯著提高了 HKDF 演算法的強度。它應該是隨機或偽隨機的,並且應與摘要函式的輸出長度相同(例如,如果使用 'SHA-256' 作為摘要,鹽值應為 256 位元的隨機資料)。
類:HmacImportParams#
hmacImportParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
類:HmacKeyAlgorithm#
hmacKeyAlgorithm.hash#
- 型別:<Algorithm>
類:HmacKeyGenParams#
hmacKeyGenParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
類:KmacImportParams#
類:KmacKeyAlgorithm#
類:KmacKeyGenParams#
類:KmacParams#
kmacParams.customization#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer> | <undefined>
customization 成員表示可選的定製化字串。
類:Pbkdf2Params#
pbkdf2Params.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
類:RsaHashedImportParams#
rsaHashedImportParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
類:RsaHashedKeyAlgorithm#
rsaHashedKeyAlgorithm.hash#
- 型別:<Algorithm>
類:RsaHashedKeyGenParams#
rsaHashedKeyGenParams.hash#
- 型別:<string> | <Algorithm>
如果表示為 <string>,該值必須是以下之一:
如果表示為 <Algorithm>,物件的 name 屬性必須是上面列出的值之一。
rsaHashedKeyGenParams.publicExponent#
- 型別:<Uint8Array>
RSA 公共指數。這必須是一個 <Uint8Array>,其中包含一個大端序、無符號且必須在 32 位內表示的整數。<Uint8Array> 可能包含任意數量的前導零位。該值必須是素數。除非有理由使用不同的值,否則請使用 new Uint8Array([1, 0, 1]) (65537) 作為公共指數。
類:RsaOaepParams#
rsaOaepParams.label#
- 型別:<ArrayBuffer> | <TypedArray> | <DataView> | <Buffer>
一組額外的位元組,這些位元組不會被加密,但會與生成的密文繫結。
rsaOaepParams.label 引數是可選的。
類:RsaPssParams#
rsaPssParams.saltLength#
- 型別:<number>
要使用的隨機鹽的長度(以位元組為單位)。
腳註
-
參見 Web Cryptography API 中的現代演算法 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24 ↩25 ↩26 ↩27 ↩28 ↩29 ↩30 ↩31 ↩32 ↩33 ↩34 ↩35 ↩36 ↩37 ↩38 ↩39 ↩40 ↩41 ↩42 ↩43 ↩44 ↩45 ↩46 ↩47 ↩48 ↩49 ↩50 ↩51 ↩52 ↩53 ↩54 ↩55 ↩56 ↩57 ↩58 ↩59 ↩60 ↩61 ↩62 ↩63 ↩64 ↩65 ↩66 ↩67 ↩68 ↩69 ↩70 ↩71 ↩72 ↩73 ↩74 ↩75 ↩76 ↩77 ↩78 ↩79 ↩80 ↩81 ↩82 ↩83 ↩84 ↩85 ↩86 ↩87 ↩88 ↩89 ↩90 ↩91 ↩92 ↩93 ↩94 ↩95 ↩96 ↩97 ↩98 ↩99 ↩100 ↩101 ↩102 ↩103 ↩104 ↩105 ↩106 ↩107 ↩108 ↩109 ↩110 ↩111 ↩112 ↩113 ↩114 ↩115 ↩116 ↩117 ↩118 ↩119 ↩120 ↩121 ↩122 ↩123 ↩124 ↩125 ↩126 ↩127 ↩128 ↩129 ↩130 ↩131 ↩132 ↩133 ↩134 ↩135 ↩136 ↩137 ↩138 ↩139 ↩140 ↩141 ↩142 ↩143 ↩144 ↩145 ↩146 ↩147 ↩148 ↩149 ↩150
-
參見 Web Cryptography API 中的安全曲線 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24