You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MongoDB中正确存储/读取AWS KMS加密的Token?

解决AWS KMS加密数据MongoDB存储与读取的问题

问题根源:KMS返回的CiphertextBlob是Uint8Array(ArrayBuffer的视图类型),直接存MongoDB会被自动序列化为带type和data字段的普通对象,取出后不再是ArrayBuffer类型,导致KMS解密时参数不合法。

正确处理流程

1. 加密后转Base64字符串存储

修改加密函数,把返回的Uint8Array转成Base64字符串,MongoDB存储标准字符串就不会丢失类型信息:

export const encryptToken = async (token) => {
    const uint8array = new TextEncoder().encode(token);
    const encryptCommand = new EncryptCommand({
        KeyId: KMS_KEY_NAME,
        Plaintext: uint8array,
    });
    const response = await client.send(encryptCommand);
    // 将Uint8Array转为Base64字符串
    return Buffer.from(response.CiphertextBlob).toString('base64');
};

2. 读取时把Base64转回Uint8Array

修改查询逻辑,把从MongoDB取出的Base64字符串转回Uint8Array,再传给解密函数:

export const getOpenAIKey = async (orgId) => {
    const docs = await (await queryDatabase(COLLECTION_NAME, { orgId })).toArray();
    if (!docs.length) {
        throw new Error(`Credentials not found for ${orgId}`);
    }
    // 对应插入时的字段名encryptedKey,原代码取key是错误的
    const encryptedKeyBase64 = docs[0].encryptedKey;
    // 把Base64转回Uint8Array
    return Uint8Array.from(Buffer.from(encryptedKeyBase64, 'base64'));
};

3. 解密函数无需修改

KMS的DecryptCommand原生支持Uint8Array作为CiphertextBlob参数,原解密函数可以直接使用:

export const decryptToken = async (cipher) => {
    const decryptCommand = new DecryptCommand({
        KeyId: KMS_KEY_NAME,
        CiphertextBlob: cipher,
    });
    const response = await client.send(decryptCommand);
    const token = new TextDecoder().decode(response.Plaintext);
    return token;
};

额外修正点

  • 插入函数里的encryptToken(Key)要改成encryptToken(openaiKey),原变量名拼写错误会导致报错;
  • 插入时存储的字段是encryptedKey,查询时必须对应取该字段,原代码取docs[0].key会拿到undefined。

内容的提问来源于stack exchange,提问作者EvyatarDot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:05:09