Google KMS非对称密钥验证失败

时间:2020-04-28 16:15:49

标签: node.js typescript digital-signature google-cloud-kms

我正在为自定义目的开发OAuth服务器实现,并尝试使用Google的KMS服务进行JWT令牌的登录/验证。

我能够很好地创建签名,问题始于验证步骤-总是导致错误(无效令牌)。然后,我继续简化代码以找到原因,最后得到了我无法进一步简化但仍然无法正常工作的代码。我基于Google KMS Docs中的示例编写了代码。

export async function sign (message: string): Promise<Buffer> {
    const name = getKeyPath();
    const digest = crypto.createHash('sha512').update(message).digest();

    const [ result ] = await client.asymmetricSign({
        name,
        digest: {
            sha512: digest
        }
    });

    return result.signature as Buffer;
}

export async function verify (message: string, signature: Buffer): Promise<boolean> {
    const publicKey = await getPublicKey();
    const verifier = crypto.createVerify('SHA512');

    verifier.write(message);
    verifier.end();

    return verifier.verify(publicKey, signature);
}

export async function getPublicKey (): Promise<string> {
    const name = getKeyPath();

    const [ publicKey ] = await client.getPublicKey({ name });

    return publicKey.pem;
}

(async () => {
    const message = 'test';
    const signature = await sign(message);
    const valid = await verify(message, signature);

    console.log(message);
    console.log(signature);
    console.log(valid);
})();

结果:

test
<Buffer 19 a2 89 37 e5 43 78 c8 63 6b 7e 19 28 10 f7 93 ad c0 fa 10 ce 0a 06 2d 79 52 58 9a a4 7c d5 77 1c 99 b2 cb ce 67 e8 93 d6 0e ef b9 f6 95 89 19 4e 28 ... 462 more bytes>
false

1 个答案:

答案 0 :(得分:1)

我的天哪,我的时间太好了。我正在rewriting the Node.js Cloud KMS samples的过程中,昨晚在调试中浪费了2个小时。我会猜测这是RSA密钥?

问题是Node丢弃/忽略了填充规范,从而导致验证失败。您必须通过构造一个关键对象来强制它使用PSS填充:

async function verify(message, signatureBuffer) {
  // Get public key
  const [publicKey] = await client.getPublicKey({
    name: 'projects/my-p/locations/.../cryptoKeyVersions/123',
  });

  // Create the verifier. The algorithm must match the algorithm of the key.
  const crypto = require('crypto');
  const verify = crypto.createVerify('sha512');
  verify.update(message);
  verify.end();

  const key = {
    key: publicKey.pem,
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING, // <-- THIS
  };

  const verified = verify.verify(key, signatureBuffer);
  return verified;
}
相关问题