【发布时间】:2021-11-07 13:45:49
【问题描述】:
我在客户端生成一对公钥/私钥并将publicKey发送到服务器,后端将在其一侧生成sharedKey并回复我publicKey,这有助于我生成sharedKey在客户端上也用于加密/解密。所以我在 Nodejs 上通过 AES-256-GCM 加密了一条消息,并在 Client 上解密了这条消息。
后端:
export function encrypt(sharedKey: string, message: string) {
const firstIv = getRandomIV();
const cipher = crypto.createCipheriv(
'aes-256-gcm',
Buffer.from(sharedKey, 'base64'),
firstIv
);
const encrypted = cipher.update(message, 'utf8');
return Buffer.from(encrypted + cipher.final()).toString('base64');
}
function getRandomIV() {
return crypto.randomBytes(12);
}
客户端:
async function decrypt(encryptedData: Uint8Array) {
const aesKey = await generateAesKey();
const nonce = encryptedData.subarray(0, SERVER_ENCRYPTION_IV_LENGTH);
const data = encryptedData.subarray(SERVER_ENCRYPTION_IV_LENGTH);
const decrypted = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: nonce,
},
aesKey,
data
);
return {
decrypted: new Uint8Array(decrypted),
decryptedString: new TextDecoder().decode(decrypted),
};
}
async function generateAesKey() {
const publicKey = await getServerPublicKey();
const privateKey = await getPrivateKey();
const sharedSecret = await crypto.subtle.deriveBits(
{
name: 'ECDH',
public: publicKey!,
},
privateKey,
256
);
const aesSecret = await crypto.subtle.digest('SHA-256', sharedSecret);
return crypto.subtle.importKey('raw', aesSecret, 'AES-GCM', true, [
'encrypt',
'decrypt',
]);
}
现在,我无法在客户端解密服务器加密响应并遇到DOMException 错误,我不知道为什么?
【问题讨论】:
-
请创建一个minimal reproducible example。您甚至没有证明您尝试过 AES 密钥是否匹配(例如,通过比较 AES 密钥的十六进制字符串)。
-
你是对的,为了你的信息,当我在客户端加密消息并在后端解密它时,它可以工作,并且后端/客户端上的
sharedKey是真的并且没有问题.正如我在问题中所写,主要问题是后端的加密阶段和客户端的解密。 -
您在 NodeJS 代码中使用的不是 GCM,而是 CTR。你应该相应地改变它。此外,您应该发布复制所需的所有功能,例如
getRandomValue()、concatUint8Array()、generateAesKey()等 -
对不起,我的问题,我更新了我的问题
-
generateAesKey函数生成的sharedKey与后端生成的相同,没有问题。
标签: node.js encryption public-key-encryption aes-gcm webcrypto-api