Насколько я знаю, пользователи не могут получить закрытые ключи от ключа хранилища ключей Azure. Только ключ publi c может быть восстановлен.
Вот образец, который я использовал для подписи и проверки:
KeyVaultClient kvc = new KeyVaultClient(AuthenticationCallback);
var key = kvc.GetKeyAsync(baseUrl, "ECDSA").GetAwaiter().GetResult();
var parameters = key.Key.ToECDsa().ExportParameters(false);
var pubKeyX = parameters.Q.X;
var pubKeyY = parameters.Q.Y;
// You can store X and Y, so that you may not need to get them from Azure Key Vault again
// Use X and Y to create ECDsa instance
var ecdsa = ECDsa.Create(new System.Security.Cryptography.ECParameters
{
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint
{
X = pubKeyX,
Y = pubKeyY
}
});
// Generate JWT
var now = DateTime.UtcNow;
var claims = new List<Claim>()
{
new Claim(JwtRegisteredClaimNames.Sub, "jack"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Email, "jack@hanxia.onmicrosoft.com", ClaimValueTypes.String)
};
var jwt = new JwtSecurityToken(
issuer: "aaa",
audience: "bbb",
claims: claims,
notBefore: now,
expires: now.AddHours(1)
);
var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary<string, string>()
{
{ JwtHeaderParameterNames.Alg, "ES256" },
{ JwtHeaderParameterNames.Kid, key.KeyIdentifier.ToString() },
{ JwtHeaderParameterNames.Typ, "JWT" }
}));
// Sign
var byteData = Encoding.UTF8.GetBytes($"{header}.{jwt.EncodedPayload}");
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var result = kvc.SignAsync(key.KeyIdentifier.ToString(), "ES256", digest).GetAwaiter().GetResult().Result;
var signature = Base64UrlEncoder.Encode(result);
// Verify
var tokenHandler = new JwtSecurityTokenHandler();
var claimsPrincipal = tokenHandler.ValidateToken($"{header}.{jwt.EncodedPayload}.{signature}", new TokenValidationParameters
{
ValidIssuer = "aaa",
ValidAudience = "bbb",
IssuerSigningKey = new ECDsaSecurityKey(ecdsa)
}, out var parsedToken);