一、数据与主密钥import crypto from 'crypto' function genDataKey(): Buffer { return crypto.randomBytes(32) } function genIv(): Buffer { return crypto.randomBytes(12) } type Envelope = { cmkId: string; iv: string; aad: string; tag: string; ciphertext: string; wrappedKey: string } 二、加密与包裹function encryptEnvelope(plain: Buffer, cmkId: string, cmk: Buffer, aad: Buffer): Envelope { const dk = genDataKey() const iv = genIv() const cipher = crypto.createCipheriv('aes-256-gcm', dk, iv) cipher.setAAD(aad) const ct = Buffer.concat([cipher.update(plain), cipher.final()]) const tag = cipher.getAuthTag() const wrapped = crypto.createCipheriv('aes-256-gcm', cmk, iv).update(dk) return { cmkId, iv: iv.toString('base64'), aad: aad.toString('base64'), tag: tag.toString('base64'), ciphertext: ct.toString('base64'), wrappedKey: wrapped.toString('base64') } } 三、解密与验证function decryptEnvelope(env: Envelope, cmk: Buffer): Buffer | null { const iv = Buffer.from(env.iv, 'base64') const aad = Buffer.from(env.aad, 'base64') const tag = Buffer.from(env.tag, 'base64') const wrapped = Buffer.from(env.wrappedKey, 'base64') const unwrap = crypto.createDecipheriv('aes-256-gcm', cmk, iv) const dk = Buffer.concat([unwrap.update(wrapped), unwrap.final()]) const dec = crypto.createDecipheriv('aes-256-gcm', dk, iv) dec.setAAD(aad) dec.setAuthTag(tag) const ct = Buffer.from(env.ciphertext, 'base64') try { return Buffer.concat([dec.update(ct), dec.final()]) } catch { return null } } 四、轮换示例type Meta = { cmkId: string } function rotateEnvelope(env: Envelope, meta: Meta, oldCmk: Buffer, newCmkId: string, newCmk: Buffer): Envelope | null { const plain = decryptEnvelope(env, oldCmk) if (!plain) return null const aad = Buffer.from(env.aad, 'base64') return encryptEnvelope(plain, newCmkId, newCmk, aad) } 五、验收清单数据密钥长度32字节(AES-256)与IV长度12字节(GCM);AAD参与认证;标签校验通过。包裹与解包均基于CMK;轮换后更新`cmkId`与`wrappedKey`,解密成功校验。元数据包含`cmkId/iv/aad/tag`等字段;异常返回`null`并记录审计。

发表评论 取消回复