use*_*730 6 c# azure .net-core azure-keyvault asp.net-core
我开始使用 Azure Keyvault 为我的应用程序存储私钥。
我有一个用例,我需要使用 RSA 私钥对 JWT 令牌进行签名。
当我的应用程序内存中有私钥时,这很容易,我会这样做
var token = new JwtSecurityToken(
issuer,
...,
claims,
...,
...,
signingCredentials_PrivateKey);
Run Code Online (Sandbox Code Playgroud)
既然开始使用Azure Keyvault,我想看看是否可以通过该KeyVaultClient.SignAsync方法对JWT令牌进行签名。
类似的东西
KeyVaultClient client = ...;
var token = new JwtSecurityToken(
issuer,
...,
claims,
...,
...);
var tokenString = client.SignAsync(myKeyIdentifier, token);
Run Code Online (Sandbox Code Playgroud)
首先,JWT 令牌由三部分组成:Header、Payload 和 Signature。它们都是 Base64UrlEncoded。
您可以通过以下方式获得签名:
HMAC-SHA256(
base64urlEncoding(header) + '.' + base64urlEncoding(payload),
secret
)
Run Code Online (Sandbox Code Playgroud)
因此,您需要生成标头和有效负载,将它们按点组合,计算散列,然后才能获得签名。
这是一个示例供您参考:
var byteData = Encoding.Unicode.GetBytes(base64urlEncoding(header) + "." + base64urlEncoding(payload));
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var signature = await keyClient.SignAsync(keyIdentifier, "RS256", digest);
var token = base64urlEncoding(header) + "." + base64urlEncoding(payload) + "." + base64urlEncoding(signature)
Run Code Online (Sandbox Code Playgroud)
SignAsync的官方 SDK 文档
JWT 的Wiki
我最终使用了杰克贾的答案
var token = new JwtSecurityToken(
issuer,
appId,
claims,
signDate,
expiryDate);
var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary<string, string>()
{
{ JwtHeaderParameterNames.Alg, "RS256" },
{ JwtHeaderParameterNames.Kid, "https://myvault.vault.azure.net/keys/mykey/keyid" },
{ JwtHeaderParameterNames.Typ, "JWT" }
}));
var byteData = Encoding.UTF8.GetBytes(header + "." + token.EncodedPayload);
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var signature = await _keyVault.SignAsync("https://myvault.vault.azure.net/keys/mykey/keyid", "RS256", digest);
return $"{header}.{token.EncodedPayload}.{Base64UrlEncoder.Encode(signature.Result)}";
Run Code Online (Sandbox Code Playgroud)
我找到了另一个解决方案,我不太喜欢它,但它与 JWT 库更好地“集成”。
var token = new JwtSecurityToken(
issuer,
appId,
claims,
signDate,
expiryDate,
new SigningCredentials(new KeyVaultSecurityKey("https://myvault.vault.azure.net/keys/mykey/keyid", new KeyVaultSecurityKey.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)), "RS256")
{
CryptoProviderFactory = new CryptoProviderFactory() { CustomCryptoProvider = new KeyVaultCryptoProvider() }
});
var handler = new JwtSecurityTokenHandler();
return handler.WriteToken(token);
Run Code Online (Sandbox Code Playgroud)
事实证明,有一个Microsoft.IdentityModel.KeyVaultExtensions扩展SecurityToken并ICryptoProvider支持 KeyVault 的库。
我的问题是
KeyVaultClient此解决方案重用现有实例。.GetAwaiter().GetResult()上KeyVaultClient.SignAsync