问题描述
使用 key Vault 的sign接口,Request Body中的 Value 是要传什么呢? 签名后的内容如何在本地离线验证呢?
Azure Key Vault Sign 接口:https://docs.microsoft.com/zh-cn/rest/api/keyvault/sign/sign#jsonwebkeysignaturealgorithm
问题答案
Azure Key Vault Sign 方法的目的是:使用指定的键从摘要创建签名。它的Body中Value的值为使用Base64编码后的内容.
签名并验证:严格来讲,此操作应该为“签名哈希”或“验证哈希”,因为 Key Vault 不支持创建签名过程中的内容哈希。 所以需要在调用Sign方法前,进行内容哈希,然后请求 Key Vault 对哈希内容进行签名。
- 支持签名哈希的验证,作为可能无法访问 [公共] 密钥材料的应用程序的一种便捷操作。 为获得最佳应用程序性能,应在本地执行 VERIFY 操作。关于密钥签名并验证请参考:https://docs.azure.cn/zh-cn/key-vault/keys/about-keys-details#key-operations
- RSASSA-PKCS-v1_5 使用 SHA-256。 必须使用 SHA-256 计算应用程序提供的摘要值,并且该值的长度必须为 32 字节。关于RS256的要求请参考:https://docs.azure.cn/zh-cn/key-vault/keys/about-keys-details#signverify
- 关于密钥、机密和证书请参考:https://docs.azure.cn/zh-cn/key-vault/general/about-keys-secrets-certificates
C#的本地离线签名验证代码:
Git Hub链接为:https://github.com/rahulpnath/Blog/blob/master/VerifySignatureOffline/VerifySignatureOffline/Program.cs , 如不能访问,可以参考以下的部分源码:
using Microsoft.Azure.KeyVault; using Microsoft.Azure.KeyVault.WebKey; using Microsoft.IdentityModel.Clients.ActiveDirectory; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace VerifySignatureOffline { class Program { private static string applicationId = "ApplicationID"; private static string applicationSecret = "ApplicationSecret"; static void Main(string[] args) { var client = new KeyVaultClient(Authenticate); GetKeys(client); Console.ReadKey(); } private static async Task<string> GetKeys(KeyVaultClient keyVaultClient) { var keyIdentifier = "keyIdentifier"; var textToEncrypt = "This is a test message"; var byteData = Encoding.Unicode.GetBytes(textToEncrypt); var hasher = new SHA256CryptoServiceProvider(); var digest = hasher.ComputeHash(byteData); var signedResult = await keyVaultClient.SignAsync( keyIdentifier, JsonWebKeySignatureAlgorithm.RS256, digest); var isVerified = await keyVaultClient.VerifyAsync(keyIdentifier, "RS256", digest, signedResult.Result); var keyResult = await keyVaultClient.GetKeyAsync(keyIdentifier); var jsonWebKey = keyResult.Key.ToString(); var key = JsonConvert.DeserializeObject<JsonWebKey>(jsonWebKey); var rsa = new RSACryptoServiceProvider(); var p = new RSAParameters() { Modulus = key.N, Exponent = key.E }; rsa.ImportParameters(p); isVerified = rsa.VerifyHash(digest, "Sha256", signedResult.Result); return null; } private static async Task<string> Authenticate(string authority, string resource, string scope) { var adCredential = new ClientCredential(applicationId, applicationSecret); var authenticationContext = new AuthenticationContext(authority, null); return (await authenticationContext.AcquireTokenAsync(resource, adCredential)).AccessToken; } } }
原文参考 Azure Key Vault: Digital Signatures and Offline Verification : https://www.rahulpnath.com/blog/azure-key-vault-digital-signatures-and-offline-verification/