Skip to content

crypto API ​

WinterTC 定义的 Web Crypto API 子集。提供密码学强度的随机数生成和 SubtleCrypto 接口。

全局对象 ​

全局对象类型描述
cryptoCryptoCrypto 接口,包含 getRandomValues 和 subtle
crypto.subtleSubtleCrypto基于 Promise 的密码学操作
CryptoKeyclass密码学密钥表示

crypto.getRandomValues() ​

用密码学强度的随机值填充一个类型化数组。

js
// 填充随机字节
let bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);

// 填充随机 32 位整数
let ints = new Uint32Array(16);
crypto.getRandomValues(ints);

// 用作随机 ID
let id = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');

支持的数组类型:Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Uint16Array、Int32Array、Uint32Array。

如果请求超过 65536 字节,抛出 QuotaExceededError。

该操作是同步的——随机字节来自 /dev/urandom(Linux)、getentropy()(macOS)或硬件 RNG(ESP32)。

crypto.subtle — SubtleCrypto ​

所有 SubtleCrypto 方法返回 Promise。可用的算法取决于构建时是否启用了 QZ_WITH_CRYPTO_EXT。

crypto.subtle.digest(algorithm, data) ​

计算密码学哈希。

js
let data = new TextEncoder().encode('hello world');

// SHA-256(始终可用)
let hash = await crypto.subtle.digest('SHA-256', data);
// 返回 ArrayBuffer

// SHA-512
let hash512 = await crypto.subtle.digest('SHA-512', data);
算法可用性
SHA-1始终可用(通过 mbedTLS)
SHA-256始终可用(通过 mbedTLS)
SHA-384始终可用(通过 mbedTLS)
SHA-512始终可用(通过 mbedTLS)

crypto.subtle.encrypt(algorithm, key, data) / decrypt(algorithm, key, data) ​

AES 加密/解密。当 QZ_WITH_CRYPTO_EXT=ON 时可用。

js
let key = await crypto.subtle.generateKey(
    { name: 'AES-CBC', length: 256 },
    false, ['encrypt', 'decrypt']
);

let iv = crypto.getRandomValues(new Uint8Array(16));
let plaintext = new TextEncoder().encode('secret message');

let ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-CBC', iv: iv },
    key, plaintext
);

let decrypted = await crypto.subtle.decrypt(
    { name: 'AES-CBC', iv: iv },
    key, ciphertext
);
算法模式密钥大小
AES-CBCencrypt, decrypt128, 192, 256
AES-CTRencrypt, decrypt128, 192, 256

crypto.subtle.generateKey(algorithm, extractable, keyUsages) ​

生成新的密码学密钥。

js
let key = await crypto.subtle.generateKey(
    {
        name: 'HMAC',
        hash: 'SHA-256'
    },
    false,  // 不可提取
    ['sign', 'verify']
);

crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages) ​

从外部数据导入密钥。

js
let rawKey = hexToBytes('0123456789abcdef0123456789abcdef');
let key = await crypto.subtle.importKey(
    'raw',
    rawKey,
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['sign', 'verify']
);

格式:"raw" 用于对称密钥。

crypto.subtle.sign(algorithm, key, data) / verify(algorithm, key, signature, data) ​

HMAC 签名与验证。

js
let key = await crypto.subtle.generateKey(
    { name: 'HMAC', hash: 'SHA-256' },
    false, ['sign', 'verify']
);

let data = new TextEncoder().encode('message');
let signature = await crypto.subtle.sign('HMAC', key, data);
let valid = await crypto.subtle.verify('HMAC', key, signature, data);
console.log('有效:', valid); // true
算法哈希选项
HMACSHA-1, SHA-256, SHA-384, SHA-512

PBKDF2 密钥派生 ​

当 QZ_WITH_CRYPTO_EXT 提供 PBKDF2 支持时可用。

js
let password = new TextEncoder().encode('password');
let salt = crypto.getRandomValues(new Uint8Array(16));

let key = await crypto.subtle.importKey(
    'raw', password, 'PBKDF2', false, ['deriveBits']
);

let derived = await crypto.subtle.deriveBits(
    { name: 'PBKDF2', salt: salt, iterations: 100000, hash: 'SHA-256' },
    key, 256
);

无 CRYPTO_EXT 时 ​

当 QZ_WITH_CRYPTO_EXT=OFF 时,只有 crypto.getRandomValues() 可用。crypto.subtle 为 undefined — 无 JS 回退。

注意事项 ​

  • 密钥提取(extractable: true)不被支持——所有密钥均不可提取
  • AES-GCM 尚不支持
  • ECDH/ECDSA(非对称)尚不支持
  • 不支持 crypto.randomUUID() —— 请使用 getRandomValues 手动构建 UUID

MIT 许可证