简体   繁体   English

如何验证在 C# 中使用 google KMS(非对称符号,椭圆曲线 P-256 密钥 SHA256 摘要)签名的签名真实性

[英]How to verify signature authenticity that was signed using google KMS (Asymmetric sign, Elliptic Curve P-256 key SHA256 Digest) in C#

I have some string data which I signed with google key defined by Algorithm: Elliptic Curve P-256 key, SHA256 Digest.我有一些字符串数据,我用算法定义的谷歌密钥签名:椭圆曲线 P-256 密钥,SHA256 摘要。 I wrote a program that should verify that the data and the signature (that was returned from KMS after the signing) and the public key are valid.我编写了一个程序来验证数据和签名(签名后从 KMS 返回)和公钥是否有效。

The problem is that I always get false.问题是我总是弄错。

For convenience, here is the code that signs the data using google KMS.为方便起见,这里是使用 google KMS 对数据进行签名的代码。 I use Google.Cloud.Kms.V1, KeyManagementServiceClient and call method AsymmetricSign that returns the signature:我使用 Google.Cloud.Kms.V1、 KeyManagementServiceClient并调用返回签名的方法AsymmetricSign

 public byte[] SignAsymmetric(string keyId, string message)
        {
            //Create the client.
            KeyManagementServiceClient client;
            GoogleCredential credential = CredentialManager.GetCredential();

            if (credential != null)
            {
                client = new KeyManagementServiceClientBuilder { ChannelCredentials = credential.ToChannelCredentials() }.Build();
            }
            else
            {
                client = new KeyManagementServiceClientBuilder().Build();
            }

            //get key enabled version
            CryptoKeyName name = new CryptoKeyName(_projectId, _locationId, _keyRingId, keyId);
            string cryptoKeyVersionId = client.ListCryptoKeyVersions(name).Where(s => s.State == CryptoKeyVersionState.Enabled).First().CryptoKeyVersionName.CryptoKeyVersionId;

            // Build the key version name.
            CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(_projectId, _locationId, _keyRingId, keyId, cryptoKeyVersionId);

            // Convert the message into bytes. Cryptographic plaintexts and
            // ciphertexts are always byte arrays.
            byte[] plaintext = Encoding.ASCII.GetBytes(message);

            // Calculate the digest.
            SHA256 sha256 = SHA256.Create();
            byte[] hash = sha256.ComputeHash(plaintext);

            // Build the digest.
            //
            // Note: Key algorithms will require a varying hash function. For
            // example, EC_SIGN_P384_SHA384 requires SHA-384.
            Digest digest = new Digest
            {
                Sha256 = ByteString.CopyFrom(hash),
            };

            // Call the API.
            AsymmetricSignResponse result = client.AsymmetricSign(keyVersionName, digest);

            // Get the signature.
            byte[] signature = result.Signature.ToByteArray();

            // Return the result.
            return signature;
        }

Now here is the code which verify the authenticity of the signature and always returns false:现在这里是验证签名真实性并始终返回 false 的代码:

 public bool VerifyAsymmetricSignature(string keyId ,string message, byte[] signature = null)
        {
            // Create the client.
            KeyManagementServiceClient client;
            GoogleCredential credential = CredentialManager.GetCredential();

            if (credential != null)
            {
                client = new KeyManagementServiceClientBuilder { ChannelCredentials = credential.ToChannelCredentials() }.Build();
            }
            else
            {
                client = new KeyManagementServiceClientBuilder().Build();
            }

            //get key enabled version
            CryptoKeyName name = new CryptoKeyName(_projectId, _locationId, _keyRingId, keyId);
            string cryptoKeyVersionId = client.ListCryptoKeyVersions(name).Where(s => s.State == CryptoKeyVersionState.Enabled).First().CryptoKeyVersionName.CryptoKeyVersionId;

            // Build the key version name.
            CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(_projectId, _locationId, _keyRingId, keyId, cryptoKeyVersionId);

            // Get the public key.
            //KeyManagementServiceClient client = KeyManagementServiceClient.Create();
            PublicKey publicKey = client.GetPublicKey(keyVersionName);

            // Split the key into blocks and base64-decode the PEM parts.
            string[] blocks = publicKey.Pem.Split("-", StringSplitOptions.RemoveEmptyEntries);
            byte[] pem = Convert.FromBase64String(blocks[1]);

            ECDsa eCDsa = ECDsa.Create();
            eCDsa.ImportSubjectPublicKeyInfo(pem, out _);

            // Convert the message into bytes. Cryptographic plaintexts and
            // ciphertexts are always byte arrays.
            //byte[] plaintext = Encoding.ASCII.GetBytes(message);

            SHA256 sha256 = SHA256.Create();
            byte[] digest = sha256.ComputeHash(Encoding.UTF8.GetBytes(message));
            // Verify the signature.
            bool verified = eCDsa.VerifyData(digest, signature, HashAlgorithmName.SHA256);

            // Return the result.
            return verified;
        }

I'm using:我正在使用:

.Net Core 5 System.Security.Cryptography.ECDsa .Net Core 5 System.Security.Cryptography.ECDsa

What am I doing wrong?我究竟做错了什么?

It is not working because Cloud KMS returns signatures in DER-encoded format.它不起作用,因为 Cloud KMS 以 DER 编码格式返回签名。 DER is part of the ITU-T Recommendation X.690 , and .NET requires signatures to be in IEEE 1363 format . DER 是ITU-T Recommendation X.690 的一部分,.NET 要求签名采用IEEE 1363 格式

Before the verification, you need to convert to IEEE 1363 using DSAConvertSignatureFormat .在验证之前,您需要使用DSAConvertSignatureFormat转换为 IEEE 1363。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从椭圆曲线 secp256k1 导出以太坊地址 - SHA256 摘要 - How to derive ethereum address from Elliptic Curve secp256k1 - SHA256 Digest 用于签名 AWS 请求的 HMAC SHA-256 - HMAC SHA-256 for a signed AWS request c# client.GetPreSignedURL in .net aws sdks 使用 HMACSHA256 而不是 AWS4-HMAC-SHA256 - c# client.GetPreSignedURL in .net aws sdks using HMACSHA256 instead of AWS4-HMAC-SHA256 在空手道框架中,如何检索由 SHA256 加密库生成的 APIGEE 令牌? - In Karate framework, How to retrieve APIGEE token generated out of SHA256 encrypted libraries? Ballerina HMAC SHA256 未生成预期结果 - Ballerina HMAC SHA256 not generating expected results AWS S3 - Etag Sha256 而不是 Md5 - AWS S3 - Etag Sha256 instead of Md5 为什么 SHA1 和 SHA256 与我的应用名称 package 不匹配? - Why SHA1 and SHA256 are not matching with my app package name? 如何使用 Cloudformation 创建 KMS 非对称签名密钥资源? - How to create KMS asymmetric signing key resource with Cloudformation? Boto3 文件上传到 S3 Bucket 未通过 SHA256 校验和检查 - Boto3 file upload to S3 Bucket is failing SHA256 checksum check 为什么我的 sha256 校验和与 aws glacier 校验和响应不兼容? - Why is my sha256 checksum incompatible with aws glacier checksum response?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM