C# 使用 Google KMS 散列和验证 JWT

C# Hash and Verify JWT using Google KMS

我们需要使用自定义 AsymmetricSecurityKey 散列和验证 JWT 令牌,该密钥使用 Google Cloud KMS API 到 sign/verify 令牌。

散列逻辑工作正常,这里是实现:

public override byte[] Sign(byte[] input)
{
    string projectId = "<PROJECT-ID>";

    string location = "global";

    var locationName = new LocationName(projectId, location);

    // Instantiate a Cloud KMS client.
    var client = KeyManagementServiceClient.Create();

    var cryptoKeyVersion = new CryptoKeyVersionName(projectId, location, "test", "asymmetric-signing-key", "1");

    var publicKey = client.GetPublicKey(cryptoKeyVersion);

    byte[] hashedInput;
    using (var hasher = SHA256.Create())
    {
        hashedInput = hasher.ComputeHash(input);
    }

    var digest = new Digest
    {
        Sha256 = ByteString.CopyFrom(hashedInput)
    };

    var asymmetricSignResponse = client.AsymmetricSign(cryptoKeyVersion, digest);

    var output = asymmetricSignResponse.Signature.ToByteArray();

    return output;
}

我需要知道如何验证签名,我尝试了很多不同的方法和库但总是失败

Google 用于创建和验证数字签名的 KMS 文档 here 没有 .NET C# 的实现

感谢您的帮助!

我找到了一个可能对您有用的存储库,它包含用于 NetCore 和 AspNet 的 KMS 示例。

此示例需要 .NET Core 2.0 或更高版本。这意味着使用 Visual Studio 2017 或命令行。

https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/kms/api

也许这个 link 对您的研究有用:

https://medium.com/google-cloud/keeping-secrets-in-asp-nets-appsettings-json-5694e533dc87

我们正在努力收集这些示例并在我们的文档中发布 (see here)。这是一个例子:

KeyManagementServiceClient client = KeyManagementServiceClient.Create();
CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(
    projectId, locationId, keyRingId, cryptoKeyId, cryptoKeyVersionId);

byte[] content = File.ReadAllBytes(contentFile);
byte[] signature = File.ReadAllBytes(signatureFile);

string pubKeyPem = client.GetPublicKey(keyVersionName).Pem;
PemReader reader = new PemReader(new StringReader(pubKeyPem));
byte[] publicKeyInfoBytes = reader.ReadPemObject().Content;
AsymmetricKeyParameter key = PublicKeyFactory.CreateKey(publicKeyInfoBytes);

// The algorithm string to use will vary depending on the algorithm associated
// with the CryptoKeyVersion. `SignerUtilities.cs` in BouncyCastle source
// contains a mapping of algorithm strings.
// "SHA512withRSA/PSS" and "SHA256withRSA" (for PKCS1) are also useful example
// values.
const string algorithm = "SHA256withECDSA";

ISigner signer = SignerUtilities.GetSigner(algorithm);
signer.Init(false, key);
signer.BlockUpdate(content, 0, content.Length);
bool verified = signer.VerifySignature(signature);

Console.Write($"Signature verified: {verified}");