当前位置: 首页 > 知识库问答 >
问题:

使用System创建带有x5c头参数的JWT令牌。识别模型。代币。jwt

司马昕
2023-03-14

我的项目正在基于构建身份验证服务。NET内核和系统。IdentityModel。代币。Jwtnuget软件包。我们希望创建包含公钥证书(或证书链)的JWT令牌,该证书可用于验证JWT数字签名。这在商业身份提供者(SaaS)中是可能的,并且在JWT规范中通过称为“x5c”的头参数得到支持。但到目前为止,我无法使用系统来实现这一点。IdentityModel。代币。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”是一种很好的方法。但我就是不能让它工作。

我曾尝试在SecurityTokenDescriptor上使用AdditionalHeaderClaims手动添加x5c,但它只是没有在令牌中输出。

有人知道怎么做吗,或者你能给我指一些关于这个主题的可靠资源吗?

顺便说一下,这就是我如何生成所使用的证书(在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的答案,代码的最后部分被更新为使用令牌。标题。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);

共有1个答案

李云
2023-03-14

x5c是什么?

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

笔记

从安全角度来看,不要使用x5c证书直接验证签名。在这种情况下,任何人都可以提供自己的证书,伪造任何身份。x5t/x5t#S256标头的目的是识别签名者——检查您是否信任x5c或x5t#S256(或其发行者)在指定的iss下提供的证书,只有这样您才应该验证签名。

因此,要构建X509链

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

if (!success) throw Error

然后针对每个链。ChainElementsvalue,获取证书属性RawValue属性(并对其进行base64编码)。

最后,您得到了x5c的字符串,并且应该只将其提供给jwt的头。

请参阅以下链接

>

从JWK生成x5c证书链

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

如何从RSACryptoServiceProvider获得x5c

希望有用。

如果问题是向标头提供x5c,则必须使用

token.Header.Add(name, value)
 类似资料:
  • 我正在寻找使用“Nimbus JOSE JWT”库开发具有RSA加密的JWT应用程序。我正在寻找示例代码。 我想使用以下Maven依赖项: 注意:请始终使用Maven Central repository的最新版本。

  • 我需要生成一个具有以下参数的JWK: > “kty”:键类型 “孩子”:密钥标识 “使用”:“sig”公钥使用 “n”:模数 “e”:“AQAB”公众指数 "x5c": X.509证书链 “x5t”:X.509证书SHA-1指纹 注: > 应包含使用“x5t”(X.509 SHA-1指纹)和“x5c”(X.509证书链)参数的X.509证书 前5个参数(kty,孩子,使用,n,e)相当简单,不是问

  • 在我的Spring Boot应用程序中,我使用JWT令牌配置了Spring OAuth2服务器。 此外,我还添加了Spring Social configuration,以便能够通过Twitter、Facebook等各种社交网络对用户进行身份验证。 这是我的配置: 此外,基于民间的答案集成Spring Security OAuth2和Spring Social我实现了,以便处理与3RDparty社

  • 我正在尝试使用谷歌云存储的JSON API从谷歌云存储中检索文件。我不允许使用SDK。是否可以从ServiceAccount.json文件创建JWT并使用JWT从Google云存储访问文件?我在node.js中有一个脚本,可以从服务帐户生成JWT,但我不确定受众是否正确 然后,我使用该JWT调用Google云存储JSON API: 使用标头: 这只会导致

  • 我有一个这样的可重装武器类: 具有以下: 并像这样使用它: 客户: 我想知道,对于命令,对于我看到的示例,除了命令正在操作的对象之外,没有其他。 此示例更改执行方法以允许使用参数。 另一个示例,更接近我在这里拥有的,在构造函数中使用参数。 在命令中包含参数是不是不好的做法/代码气味,在这种情况下是带有项目符号数的?