C# 使用来自授权端点 (crv, x, y) 的值验证 JWT 令牌
Posted
技术标签:
【中文标题】C# 使用来自授权端点 (crv, x, y) 的值验证 JWT 令牌【英文标题】:C# Validate JWT token with values from an authorize end point (crv, x, y) 【发布时间】:2020-12-23 17:36:42 【问题描述】:我有一个网页正在 iframe 中的供应商网站上显示。他们调用我的页面并在查询字符串中传递一个 JWT。我必须解析 jwt。
eyJraWQiOiIyMDIwLTA5LTAyVDE3OjM2OjE3LjU3MC5lYyIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJzdWIiOiJ1cm46Y2VybmVyOmlkZW50aXR5LWZlZGVyYXRpb246cmVhbG06SFdPb0lsUlgyWWRGZjkyNGJBZTZSR0l5WmtuajZrTjctY2g6cHJpbmNpcGFsOnRhNDh6OWdkNTVkNndyNW0iLCJhdWQiOiJodHRwczpcL1wvdXJsMjU4dmowai5leGVjdXRlLWFwaS51cy1lYXN0LTIuYW1hem9uYXdzLmNvbSIsImlzcyI6Imh0dHBzOlwvXC9kZXYuYmF5Y2FyZS5wYXRpZW50cG9ydGFsLnVzLTEuaGVhbHRoZWludGVudC5jb20iLCJleHAiOjE1OTkxNTQ1MTYsImlhdCI6MTU5OTE1MzkxNiwic2lkIjoiZGUwNmJhNmUtYjQyYy00ZmY5LWI4MmQtYmM4NjY0ODJmODU4In0.6Ru5Lyd1Zq016uv84pP-GjSuz6koVNipa_cd939eF21-5N2_A0Nj3I6AkDhuHrE870WzyTiCmZfkIjMOFZkRCA
我想通过从https://authorizion.x.com/jwk 中提取值来验证签名。我得到的值如下所示:
"keys":[
"kty":"EC",
"crv":"P-256",
"kid":"2020-09-04T18:16:04.934.ec",
"x":"82WEbXbnfGC1kmMfjJch6gFJRp7hEp08gzZQdBLLFIk",
"y":"ytkPwl4IjLw8M94DzgTmdAbxjq0AmmYu9mMmxpU3eBI"
,
"kty":"EC",
"crv":"P-256",
"kid":"2020-09-02T17:36:17.570.ec",
"x":"uAfEPKELRuUVMtB0DCB5oyYWnfiV8-9zHYntvI0lsRE",
"y":"32J6nVgeb9RLdWK21QNDHhWdOsZJbxvyEq2n0IOvLtQ"
,
"kty":"EC",
"crv":"P-256",
"kid":"2020-08-31T17:36:17.359.ec",
"x":"HsxFY2vihycZgYnkSTLDHJ0Cagr2nUcZTbf2yQKPS6A",
"y":"4kLClPGM0TG_gCUlBKkYdXrlLFVasPxQ2UOvwSBKyt0"
]
我根据 JWT 标头中的 Kid 值选择密钥。如何根据 crv、x 和 y 值验证签名?似乎我需要公共或私人证书,但我没有。
我还能补充什么。它使用 ECDSA p-256 加密。上面有一个 Json Web Token,在 jwt.io 我得到以下值,
标题
"kid": "2020-09-02T17:36:17.570.ec",
"typ": "JWT",
"alg": "ES256"
有效载荷
"sub": "urn:cerner:identity-federation:realm:HWOoIlRX2YdFf924bAe6RGIyZknj6kN7-ch:principal:ta48z9gd55d6wr5m",
"aud": "https://url258vj0j.execute-api.us-east-2.amazonaws.com",
"iss": "https://dev.baycare.patientportal.us-1.healtheintent.com",
"exp": 1599154516,
"iat": 1599153916,
"sid": "de06ba6e-b42c-4ff9-b82d-bc866482f858"
签名
6Ru5Lyd1Zq016uv84pP-GjSuz6koVNipa_cd939eF21-5N2_A0Nj3I6AkDhuHrE870WzyTiCmZfkIjMOFZkRCA
我包含了与 JWT 匹配的 Java Web 密钥集。
【问题讨论】:
【参考方案1】:这是一个基于Jose 的非常简短的解决方案。
基本上你需要从给定的 URL 中读取 JWKS,选择正确的 JWK 与匹配的密钥 ID (kid
),根据给定的、Base64 编码、x
和 y
创建一个 ECJWKey
参数,然后使用该密钥验证 JWT:
以下源代码只是对该过程的简短说明,密钥是硬编码的,不是从 JWKS 端点读取的。
using Jose;
using System;
using System.Security.Cryptography;
namespace JWKValiadation
public class ECJWKey
public string kty get; set;
public string crv get; set;
public string kid get; set;
public string x get; set;
public string y get; set;
class Program
static void Main(string[] args)
ECJWKey ecjwkkey = new ECJWKey
kty = "EC",
crv = "P-256",
kid = "2020-09-02T17:36:17.570.ec",
x = "uAfEPKELRuUVMtB0DCB5oyYWnfiV8-9zHYntvI0lsRE",
y = "32J6nVgeb9RLdWK21QNDHhWdOsZJbxvyEq2n0IOvLtQ"
;
string tokenEC = "eyJraWQiOiIyMDIwLTA5LTAyVDE3OjM2OjE3LjU3MC5lYyIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJzdWIiOiJ1cm46Y2VybmVyOmlkZW50aXR5LWZlZGVyYXRpb246cmVhbG06SFdPb0lsUlgyWWRGZjkyNGJBZTZSR0l5WmtuajZrTjctY2g6cHJpbmNpcGFsOnRhNDh6OWdkNTVkNndyNW0iLCJhdWQiOiJodHRwczpcL1wvdXJsMjU4dmowai5leGVjdXRlLWFwaS51cy1lYXN0LTIuYW1hem9uYXdzLmNvbSIsImlzcyI6Imh0dHBzOlwvXC9kZXYuYmF5Y2FyZS5wYXRpZW50cG9ydGFsLnVzLTEuaGVhbHRoZWludGVudC5jb20iLCJleHAiOjE1OTkxNTQ1MTYsImlhdCI6MTU5OTE1MzkxNiwic2lkIjoiZGUwNmJhNmUtYjQyYy00ZmY5LWI4MmQtYmM4NjY0ODJmODU4In0.6Ru5Lyd1Zq016uv84pP-GjSuz6koVNipa_cd939eF21-5N2_A0Nj3I6AkDhuHrE870WzyTiCmZfkIjMOFZkRCA";
// first read the header to get the kid
var headers = Jose.JWT.Headers(tokenEC);
if(headers.TryGetValue("kid", out var keyId))
// in a real application you would need the kid
// to select the right key from the JKWS
Console.WriteLine(keyId);
// create the key based on the parameters from the JWK
ECDsa eckey = ECDsa.Create(new ECParameters
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint
X = Base64Url.Decode(ecjwkkey.x),
Y = Base64Url.Decode(ecjwkkey.y)
);
// verify and decode the token
string payload = Jose.JWT.Decode(tokenEC, eckey);
Console.WriteLine(payload);
【讨论】:
太棒了。简洁明了的工作示例。我希望这可以帮助其他人!谢谢你。我正在编码为base 64而不是解码。现在好多了。以上是关于C# 使用来自授权端点 (crv, x, y) 的值验证 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章
Kong Basic Auth 使用来自其他服务的身份验证来授权路由请求
来自 C# HttpClient 针对 Spring 服务器 JWT 令牌的身份验证