Node.js与C#中Scrypt密钥派生不一致致AES-GCM解密失败排查
Node.js与C#中Scrypt密钥派生不匹配导致AES-GCM解密失败问题
我有一个具备数据库访问能力的Node.js应用,从JSON文件获取连接字符串,其中密码部分包含经AES-GCM加密的salt、nonce和密文。加密解密密码的密钥通过Node.js内置crypto库的Scrypt算法派生,Node.js端加解密正常。
但在C#应用中使用该连接字符串时,无法解密密码,报错:
The computed authentication tag did not match the input authentication tag
已定位问题出在密钥派生环节,找不到与Node.js匹配的.NET实现。已确认调用函数前salt和secret在Node.js与C#中值一致,但派生的密钥始终不同。
Node.js 解密代码
decrypt(encryptedText) { const decoded = Buffer.from(encryptedText, "base64").toString("utf8"); const [saltHex, ivHex, authTagHex, encryptedHex] = decoded.split(":"); const salt = Buffer.from(saltHex, "hex"); const secretByte = Buffer.from(this.secretKey, "utf-8"); const key = crypto.scryptSync(salt, secretByte, 32, { cost: 16384, blockSize: 8, parallelization: 1 }); const iv = Buffer.from(ivHex, "hex"); const authTag = Buffer.from(authTagHex, "hex"); const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv); decipher.setAuthTag(authTag); let decrypted = decipher.update(encryptedHex, "hex", "utf8"); decrypted += decipher.final("utf8"); return decrypted; }
C# 解密代码
public static String DecryptAESGCM(Dictionary<string, byte[]> encrypted, string secret) { byte[] secretByte = Encoding.UTF8.GetBytes(secret); //clsLogger.Log(Encoding.UTF8.GetString(encrypted.GetValueOrDefault("salt")), enumLogLevel.INFO); // Derive key byte[] derivedKey = SCrypt.ComputeDerivedKey(secretByte, encrypted.GetValueOrDefault("salt"), 16384, 8, 1, 1, 32); using (AesGcm aes = new AesGcm(derivedKey, encrypted.GetValueOrDefault("tag").Length)) { byte[] plainText = new byte[encrypted.GetValueOrDefault("cipher").Length]; aes.Decrypt(encrypted.GetValueOrDefault("nonce"), encrypted.GetValueOrDefault("cipher"), encrypted.GetValueOrDefault("tag"), plainText); return Encoding.UTF8.GetString(plainText); } }
C#中的字典存储了salt、nonce、tag和cipher对应的byte[]数据。请问有人遇到过类似问题并解决,或有相关思路吗?
感谢!
内容的提问来源于stack exchange,提问作者RobinGFT
相关产品推荐
相关产品推荐

