使用天蓝色的密钥库验证JWT签名始终返回false

时间:2019-07-19 11:10:15

标签: c# jwt signing azure-keyvault

我正在尝试使用Azure keyvault客户端验证签名,但是它始终返回false。

我设法使用KeyVaultClient.SignAsync方法对其进行签名,但是,当尝试使用KeyVaultClient.VerifyAsync时,结果总是返回false。

// Added for completeness, this method seems to be working correctly
private static async Task<string> SignJwt(KeyVaultClient client)
{
    var claimsToSign = new[]
    {
        new Claim("sub", "UserId123"),
        new Claim("custom", "MyValue")
    };

    var token = new JwtSecurityToken(
        issuer: "AuthApp",
        audience: "Consumer",
        claims: claimsToSign
    );

    var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary<string, string>()
    {
        {JwtHeaderParameterNames.Alg, JsonWebKeySignatureAlgorithm.ES256},
        {JwtHeaderParameterNames.Typ, "JWT"}
    }));

    var byteData = Encoding.UTF8.GetBytes(header + "." + token.EncodedPayload);
    var hasher = new SHA256CryptoServiceProvider();
    var digest = hasher.ComputeHash(byteData);

    var signature = await client.SignAsync(KeyVaultBaseUrl, KeyName, KeyVersion, JsonWebKeySignatureAlgorithm.ES256, digest);

    var fullJwt = $"{header}.{token.EncodedPayload}.{Base64UrlEncoder.Encode(signature.Result)}";

    return fullJwt;
}

// This always returns a false result
private static async Task<KeyVerifyResult> ValidateJwt()
{
    // Example of a JWT produced by the SignJwt method
    var jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJVc2VySWQxMjMiLCJjdXN0b20iOiJNeVZhbHVlIiwiaXNzIjoiQXV0aEFwcCIsImF1ZCI6IkNvbnN1bWVyIn0.6tYkBcoFojJVJBhdNST49v4A3VWC1Rqizx_FzmSRICQubDEfXVopfP7Rs9tOBi9YzTCbod9o3hmHzIxANoIh7A";

    var client = new KeyVaultClient(GetAccessTokenAsync, new HttpClient());

    var jwtParts = jwt.Split('.');
    var header = jwtParts[0];
    var body = jwtParts[1];
    var signature = Encoding.UTF8.GetBytes(Base64UrlEncoder.Decode(jwtParts[2]));

    var byteData = Encoding.UTF8.GetBytes($"{header}.{body}");
    var hasher = new SHA256CryptoServiceProvider();
    var digest = hasher.ComputeHash(byteData);

    var verified = await client.VerifyAsync(KeyVaultBaseUrl, KeyName, KeyVersion, JsonWebKeySignatureAlgorithm.ES256, digest, signature);
    return verified;
}


private static async Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
{
    var appCredentials = new ClientCredential(ClientId, ClientSecret);
    var context = new AuthenticationContext(authority, TokenCache.DefaultShared);

    var result = await context.AcquireTokenAsync(resource, appCredentials);

    return result.AccessToken;
}

有什么想法为什么ValidateJwt总是返回false而不是true?

1 个答案:

答案 0 :(得分:0)

解决了。

对于感兴趣的任何人,我都没有正确地使用SignJwt方法对签名进行64位编码:

使用Base64UrlEncoder.Encode/Decode代替使用Convert.ToBase64String/FromBase64String