使用System.IdentityModel.Tokens.Jwt使用x5c标头参数创建JWT令牌

Grubl3r

我的项目正在基于.NET Core和System.IdentityModel.Tokens.Jwtnuget包构建身份验证服务我们要创建包含公共密钥证书(或证书链)的JWT令牌,这些令牌可用于验证JWT数字签名。商业身份提供商(SaaS)可以做到这一点,并且在JWT规范中通过称为“ x5c”的标头参数来支持。但到目前为止,我一直无法使用它System.IdentityModel.Tokens.Jwt

我能够创建使用证书签名的JWT令牌。证书是自签名的,并使用openssl(下面包含的命令)创建。我在C#中的测试代码如下所示:

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
// more usings..

public static string GenerateJwtToken(int exampleAccountId, string x509CertFilePath, string x509CertFilePassword)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var signingCert = new X509Certificate2(x509CertFilePath, x509CertFilePassword);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, exampleAccountId.ToString()) }),
        Expires = DateTime.UtcNow.AddDays(30),
        Audience = "myapp:1",
        Issuer = "self",
        SigningCredentials = new X509SigningCredentials(signingCert, SecurityAlgorithms.RsaSha512Signature),
        Claims = new Dictionary<string, object>()
        {
            ["test1"] = "hello world",
            ["test2"] = new List<int> { 1, 2, 4, 9 }
        }
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

生成的令牌头在jwt.io中反序列化为:

{
  "alg": "RS512",
  "kid": "193A49ED67F22850F4A95258FF07571A985BFCBE",
  "x5t": "GTpJ7WfyKFD0qVJY_wdXGphb_L4",
  "typ": "JWT"
}

问题是,我也想获取“ x5c”标头参数输出。这样做的原因是,我的项目正在尝试将证书与公钥包括在一起,以验证令牌本身内部的令牌签名,而“ x5c”是实现此目的的好方法。但是我无法使它正常工作。

我尝试使用AdditionalHeaderClaimson手动添加x5c SecurityTokenDescriptor,但是令牌中没有输出它。

有人知道该怎么做吗,或者您可以指出一些有关该主题的可靠资源吗?

顺便说一下,这就是我生成使用的证书的方式(在Windows上):

openssl genrsa -out private2048b.key 2048 

openssl req -new -key private2048b.key -out myrequest2048.csr -config <path to openssl.cfg>

openssl x509 -req -days 3650 -in myrequest2048.csr -signkey private2048b.key -out public2048b.crt

openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in public2048b.crt -inkey private2048b.key -out mypkcs2048.pfx -name "Testtest"

PFX是代码中正在读取和使用的文件。

后代更新

使用Abdulrahman Falyoun的答案,对代码的最后一部分进行了更新,以用于token.Header.Add在序列化JWT令牌之前手动添加“ x5c”标头参数。令牌必须转换为JwtSecurityToken。这项工作有效,并在https://jwt.io中创建了一个有效的令牌(并具有可以立即验证的签名)

// create JwtSecurityTokenHandler and SecurityTokenDescriptor instance before here..

var exportedCertificate = Convert.ToBase64String(signingCert.Export(X509ContentType.Cert, x509CertFilePassword));
 
// Add x5c header parameter containing the signing certificate:
var token = tokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;
token.Header.Add(JwtHeaderParameterNames.X5c, new List<string> { exportedCertificate });
 
return tokenHandler.WriteToken(token);
阿卜杜勒·拉赫曼·法永

什么是x5c?

“ x5c”(X.509证书链)标头参数包含与用于对JWS进行数字签名的密钥相对应的X.509公钥证书或证书链[RFC5280]。证书或证书链表示为证书值字符串的JSON数组。数组中的每个字符串都是以base64编码(不是base64url编码)的DER [ITU.X690.2008] PKIX证书值。包含与用于对JWS进行数字签名的密钥相对应的公用密钥的证书必须是第一证书。可以附加其他证书,随后的每个证书都是用来证明前一个证书的证书。接收者必须根据RFC 5280 [RFC5280]验证证书链,并且如果发生任何验证失败,则认为证书或证书链无效。

注意

从安全角度考虑-不要使用x5c证书直接验证签名。在那种情况下,任何人都可以提供自己的证书并欺骗任何身份。如果x5t / x5t#S256标头用于标识签名者,请检查您是否信任在指定的iss下由x5c或x5t#S256(或其发行者)提供的证书,然后才应验证签名。

所以建立X509链

X509Chain chain = new X509Chain()
bool success = chain.Build(cert);

if (!success) throw Error

然后,对于每个chain.ChainElements值,使用Certificate属性RawValue属性(并对其进行base64编码)。

最后,您获得的字符串,x5c并且应仅将其提供给的标头jwt

见以下链接

创建包含证书的JWK集

从JWK生成x5c证书链

如何获取JWK并在JWT签名中使用它们?

如何从RSACryptoServiceProvider获取x5c

希望它有用。

#编辑

如果问题是提供x5c给标题,则必须使用添加

token.Header.Add(name, value)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在ASP.NET 5中使用System.IdentityModel.Tokens.Jwt编码JWT令牌

使用System.IdentityModel.Tokens.Jwt验证C#中生成的令牌

使用System.IdentityModel.Tokens.Jwt解码和验证JWT令牌

如何使用System.IdentityModel.Tokens.Jwt包提取令牌到期时间

带有System.IdentityModel.Tokens.Jwt版本5.1.4的JWT令牌

IDX10501:签名验证失败。尝试使用的密钥:“ System.IdentityModel.Tokens.X509AsymmetricSecurityKey”

System.IdentityModel.Tokens.JwtSecurityToken定制属性

WCF:EncryptedKey子句未使用必需的加密令牌'System.IdentityModel.Tokens.X509SecurityToken'包装

没有发行者的System.Identitymodel.Tokens.jwt可能吗?

System.IdentityModel.Tokens.Jwt的更新导致IdentityServer3 Client中的重大更改

在Azure上部署后无法加载文件或程序集'System.IdentityModel.Tokens.Jwt

名称空间System.IdentityModel.Tokens中不存在“ Jwt”-仅在生产中

System.IdentityModel.Tokens.SessionSecurityTokenHandler和System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler DLL在哪里

如何使用System.IdentityModel.Tokens.Jwt使用Google OAuth2兼容算法RSA SHA-256生成JWT?

System.IdentityModel.Tokens和Microsoft.IdentityModel.Tokens之间的冲突

使用System.IdentityModel.Tokens.Jwt从1.1迁移到2.0后,JWTAuthentication无法在ASP.NET Core 2.0中工作-5.1.4更新

如何使用.NET 5的IdentityModel扩展生成JWT令牌

System.IdentityModel.Tokens和Microsoft.IdentityModel.Tokens有什么区别?我应该在ASP.NET Core应用程序中使用哪一个?

.Net 6 的 System.IdentityModel.Tokens.Jwt 的自定义对象 JSON 序列化实现是否存在问题?

无法解析类型“System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel”

如何在asp.net核心中为JwtBearer和System.IdentityModel.Tokens.Jwt自定义Bearer标头关键字?

无法从“ Microsoft.IdentityModel.Tokens.SymmetricSecurityKey”转换为“ Microsoft.IdentityModel.Tokens.SigningCredentials”

使用带有IdentityModel 4.1.1的刷新令牌的请求访问令牌

使用.NET 4.5(System.IdentityModel)/ WIF解密SAML 2声明

为 .NET Core 3.1/IdentityModel 5.1 使用 ResourceOwnerPassword 流

如何在最新的Microsoft.IdentityModel.Clients.ActiveDirectory中使用PromptBehavior来获取令牌

我无法使用“Stripe.tokens.create”创建条纹令牌

无法使用 IdentityModel.OidcClient2 使用 WinForms 应用程序登录到 IdentityServer4

“” error_description“:”引发了类型为'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException'的异常。“