javascript - 关于使用 Cloud KMS 进行签名验证的问题
问题描述
我正在尝试验证使用 Google 的云 KMS 生成的签名,但我不断收到无效响应。
这是我测试它的方式:
const versionName = client.cryptoKeyVersionPath(
projectId,
locationId,
keyRingId,
keyId,
versionId
)
const [publicKey] = await client.getPublicKey({
name: versionName,
})
const valueToSign = 'hola, que tal'
const digest = crypto.createHash('sha256').update(valueToSign).digest()
const [signResponse] = await client.asymmetricSign({
name: versionName,
digest: {
sha256: digest,
},
})
const valid = crypto.createVerify('sha256').update(digest).verify(publicKey.pem, signResponse.signature)
if (!valid) return console.log('INVALID SIGNATURE')
console.log('SIGNATURE IS VALID!')
// output: INVALID SIGNATURE
除非我使用原始消息而不是其哈希值,否则此代码将始终记录“无效签名” :
const valid = crypto.createVerify('sha256').update(valueToSign).verify(publicKey.pem, signResponse.signature) // true
但是使用本地私钥,我可以对消息进行签名并使用它们的哈希验证它们:
const valueToSign = 'hola, the tal'
const msgHash = crypto.createHash("sha256").update(valueToSign).digest('base64');
const signer = crypto.createSign('sha256');
signer.update(msgHash);
const signature = signer.sign(pk, 'base64');
const verifier = crypto.createVerify('sha256');
verifier.update(msgHash);
const valid = verifier.verify(pubKey, signature, 'base64');
console.log(valid) // true
为什么?kms签名有什么不同吗?
解决方案
根据加密模块文档中的这个示例和您的观察,我想说您可能误解了它的client.asymmetricSign
工作原理。让我们分析一下会发生什么:
您的本地私钥代码:
const valueToSign = 'hola, the tal'
// Create sha256 hash
const msgHash = crypto.createHash("sha256").update(valueToSign).digest('base64');
// Let signer sign sha256(hash)
const signer = crypto.createSign('sha256');
signer.update(msgHash);
const signature = signer.sign(pk, 'base64');
// We now got sign(sha256(hash))
// Let verifier verify sha256(hash)
const verifier = crypto.createVerify('sha256');
verifier.update(msgHash);
const valid = verifier.verify(pubKey, signature, 'base64');
console.log(valid) // true
我们正在sign(sha256(hash))
使用verify(sha256(hash))
.
您的 KMS 代码:
const valueToSign = 'hola, que tal'
// Create sha256 hash
const digest = crypto.createHash('sha256').update(valueToSign).digest()
// Let KMS sign the hash
const [signResponse] = await client.asymmetricSign({
name: versionName,
digest: {
sha256: digest, // we already say "we hashed our data using sha256"
},
});
// We now got `sign(hash)`, NOT `sign(sha256(hash))` (where hash == digest)
// Let verifier verify sha256(hash)
const valid = crypto.createVerify('sha256').update(digest).verify(publicKey.pem, signResponse.signature)
我们正在sign(hash)
使用verify(sha256(hash))
.
基本上,您在本地对哈希进行签名并验证签名的哈希。使用 KMS,您正在对数据进行签名并验证签名的哈希,这实际上是您的签名数据,因此您第二次尝试使用.update(valueToSign)
作品。
解决方案?在让 KMS 签名之前再次散列你的 sha256 散列,因为KMS 期望待签名数据的 sha256 散列,而crypto
期望待签名数据(给定你传递给的算法,它会自行散列createSign
) .
推荐阅读
- openid - Keycloak 使用两个状态参数重定向到另一个 oidc
- django - 如何将“所有者”与默认用户模型相关联?
- docker - Kubernetes 中的容器标签
- mysql - 将 mysql json 查询结果导出到 json 文件的最佳方法?
- awk - 用第二个文件中的文本替换文件中的字符串
- python - calling method in python to increase the age of the animal
- cmake - 架构文件的额外 interface_include_directories。可能吗?
- android - AOSP构建镜像编译错误android 7
- xcode - 配置文件与 com.apple.security.application-groups 权利的权利文件值不匹配
- javascript - 如何在 html 标头中加载可选择的 javascript