我正在尝试将 Mac 的AquaticPrime框架移植到 Windows。
在 Mac 上,它使用 opensll 库,我尝试了解如何将其移植到 Windows,我猜我必须使用 CryptoAPI。
我主要需要使用给定公钥验证生成的签名的代码。
以下是使用 openssl 完成验证的方式:
- 输入:许可证数据、公钥和签名,均为 128 字节长。
- SHA1 摘要是根据许可证数据计算得出的。
- 使用公钥数据设置 RSA 上下文
- RSA_public_decrypt() 被调用,给定 RSA 密钥和签名,它返回一个 20 字节长的 SHA1 摘要 - 这个摘要是否等于第 2 步中的摘要,签名是有效的。
那么,如何使用 CryptoAPI 做到这一点?我已经做到了这一点:
- 从 CryptAcquireContext(ctx, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) 开始
- 在这篇文章的帮助下使用 CryptImportKey ,pubexp=3 和 bitlen=1024。一切正常,即我没有收到任何错误,我查看了二进制数据以验证它是否与 MSDN 文章显示的内容相匹配。
- 从许可证数据创建 SHA1 摘要。我检索了生成的 20 字节哈希值,并看到它与我在 Mac 上使用 openssl 获得的值相匹配。
此时,我调用:
CryptVerifySignature (hashHdl, sig, sigLen, keyHdl, 0, 0)
此操作失败,错误代码为 ERROR_INVALID_PARAMETER。
奇怪的是,当我第一次不小心将两倍大的公钥存储到 PUBLICKEYBLOB 结构中时,我收到了 NTE_BAD_SIGNATURE 错误。这可能表明现在我传递的公钥是正确的。
那么,为什么现在出现 ERROR_INVALID_PARAMETER 错误呢?我已经验证了哈希值是正确的,并且密钥似乎也被接受了。而“sig”参数只是一个指向签名的128字节的指针,sigLen是128。
那么,我在这里缺少什么?