Security.Jwt

Security.Jwt

实现JWT密钥的自动生成与轮换管理

NetDevPack.Security.Jwt是专为.NET设计的JWT密钥管理组件。它能自动创建和轮换RSA或ECDsa密钥,支持JWE,提供公共jwks_uri端点,并扩展客户端API以使用JWKS端点。该组件遵循NIST最佳实践,每90天轮换密钥并移除旧私钥,采用RFC 7518推荐的RSA和ECDSA设置。通过简化JWT密钥管理流程,它显著提升了应用安全性,尤其适合负载均衡环境。

JWT密钥管理安全性API认证IdentityServer4Github开源项目

.NET的JWT密钥管理 - 为您的Jwt(jws) / Jwe生成和自动轮换加密密钥

密钥管理最大的问题之一是:如何安全地分发密钥。HMAC依赖于在多个项目之间共享密钥。为了实现这一点,NetDevPack.Security.Jwt使用公钥加密系统来生成您的密钥。因此您可以在https://<your_api_adrress>/jwks共享您的公钥!

<p align="center"> <img alt="read before" src="https://yellow-cdn.veclightyear.com/2b54e442/de951652-7cb4-4a4e-8fe0-686412036a76.png" /> </p>

您是这样创建Jwt的吗?

<p align="center"> <img alt="read before" src="https://yellow-cdn.veclightyear.com/2b54e442/c01a4c3c-f201-4a4b-9ffb-4fcc8f23ecc1.png" /> </p>

让我告诉您:您有一个问题。


<br>

NugetcoverageNetDevPack - MASTER Publish

该项目的目标是通过管理您的JWT来帮助提高应用程序的安全性。

  • 自动创建RSA或ECDsa密钥
  • 支持JWE
  • 支持公共jwks_uri端点,以JWKS格式提供您的公钥
  • 为您的客户端API提供扩展以使用JWKS端点。详见NetDevack.Security.JwtExtensions
  • 每90天自动轮换密钥(遵循NIST公钥轮换最佳实践)
  • 密钥轮换后删除旧的私钥(NIST建议)
  • 使用RSA和ECDSA的推荐设置(RFC 7518建议)
  • 使用随机数生成器为带AES CBC的JWE生成密钥(dotnet不支持带Aes128GCM的RSA-OAEP)
  • 默认将密钥保存在与ASP.NET DataProtection相同的位置(ASP.NET保存用于加密MVC cookie的密钥的同一位置)

它使用RSA和ECDsa算法生成更好的密钥。这是RFC 7518最推荐的。

令牌验证

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "https://www.devstore.academy", ValidAudience = "NetDevPack.Security.Jwt.AspNet" }; }); builder.Services.AddAuthorization(); builder.Services.AddJwksManager().UseJwtValidation();

生成令牌:

public AuthController(IJwtService jwtService) { _jwtService = jwtService; } private string GenerateToken(User user) { var key = _jwtService.GetCurrentSigningCredentials(); // (ECDsa或RSA)自动生成的密钥 var handler = new JsonWebTokenHandler(); var now = DateTime.Now; var descriptor = new SecurityTokenDescriptor { Issuer = "https://www.devstore.academy", // <- 您的网站 Audience = "NetDevPack.Security.Jwt.AspNet", IssuedAt = now, NotBefore = now, Expires = now.AddMinutes(60), Subject = new ClaimsIdentity(FakeClaims.GenerateClaim().Generate(5)), SigningCredentials = await service.GetCurrentSigningCredentials() }; return tokenHandler.WriteToken(token); }
<p align="center"> <img width="100px" src="https://jpproject.blob.core.windows.net/images/helldog-site.png" /> </p>

目录


🛡️ 这是什么

JSON Web密钥集(JWKS)是用于验证授权服务器颁发的JSON Web令牌(JWT)的公钥集合。该组件的主要目标是为您的JWKS提供集中存储和密钥轮换,同时遵循JWKS生成的最佳实践。它具有IdentityServer4插件,可以每90天自动轮换jwks_uri,并无缝管理您的jwks_uri。

如果您的API或OAuth 2.0部署在Kubernetes或Docker Swarm的负载均衡器下,则此组件至关重要。它的功能类似于ASP.NET Core中的DataProtection Key。

该组件生成、存储和管理您的JWKS,同时维护跨实例可访问的集中存储。默认情况下,每三个月生成一个新密钥。

您可以通过JWKS端点公开您的JWKS并与您的API共享。

ℹ️ 安装

要在您的API中安装NetDevPack.Security.Jwt,请在NuGet包管理器控制台中使用以下命令:

Install-Package NetDevPack.Security.Jwt

或者,您可以使用.NET Core命令行界面:

dotnet add package NetDevPack.Security.Jwt

接下来,修改Startup.csprogram.cs文件中的Configure方法:

builder.Services.AddJwksManager().UseJwtValidation();

❤️ 令牌生成

在大多数情况下,当我们说JWT时,实际上是指JWS。

public AuthController(IJwtService jwtService) { _jwtService = jwtService; } private string GenerateToken(User user) { var tokenHandler = new JwtSecurityTokenHandler(); var currentIssuer = $"{ControllerContext.HttpContext.Request.Scheme}://{ControllerContext.HttpContext.Request.Host}"; var key = _jwtService.GetCurrentSigningCredentials(); // (ECDsa或RSA)自动生成的密钥 var token = tokenHandler.CreateToken(new SecurityTokenDescriptor { Issuer = currentIssuer, Subject = identityClaims, Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = key }); return tokenHandler.WriteToken(token); }

✔️ 令牌验证 (JWS)

使用相同的服务获取当前密钥并验证令牌。

public AuthController(IJwtService jwtService) { _jwtService = jwtService; } private string ValidateToken(string jwt) { var handler = new JsonWebTokenHandler(); var currentIssuer = $"{ControllerContext.HttpContext.Request.Scheme}://{ControllerContext.HttpContext.Request.Host}"; var result = handler.ValidateToken(jwt, new TokenValidationParameters { ValidIssuer = currentIssuer, SigningCredentials = _jwtService.GetCurrentSigningCredentials() }); result.IsValid.Should().BeTrue(); }

⛅ 多个API - 使用Jwks

密钥管理的一个主要挑战是安全地分发密钥。HMAC依赖于在多个项目之间共享密钥。为解决这个问题,NetDevPack.Security.Jwt使用公钥密码系统来生成密钥。因此,您可以在https://<your_api_address>/jwks共享您的公钥!

简单明了 🎂

身份API(发出令牌的API)

在发出JWT令牌的API中安装NetDevPack.Security.Jwt.AspNetCore。修改您的Startup.cs:

public void Configure(IApplicationBuilder app) { app.UseJwksDiscovery().UseJwtValidation(); }

生成令牌:

private string EncodeToken(ClaimsIdentity identityClaims) { var tokenHandler = new JwtSecurityTokenHandler(); var currentIssuer = $"{ControllerContext.HttpContext.Request.Scheme}://{ControllerContext.HttpContext.Request.Host}"; var key = _jwksService.GetCurrentSigningCredentials(); var token = tokenHandler.CreateToken(new SecurityTokenDescriptor { Issuer = currentIssuer, Subject = identityClaims, Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = key }); return tokenHandler.WriteToken(token); }

客户端API

在需要JWT验证的客户端API中,安装NetDevPack.Security.JwtExtensions。然后,更新您的Startup.cs:

public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(x => { x.RequireHttpsMetadata = true; x.SaveToken = true; // 将公钥保存在缓存中10分钟。 x.IncludeErrorDetails = true; // <- 便于调试 x.SetJwksOptions(new JwkOptions("https://localhost:5001/jwks")); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... app.UseAuthentication(); app.UseAuthorization(); // ... }

在你的Controller中:

[Authorize] public class IdentityController : ControllerBase { public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }

完成 👌!

💾 存储

默认情况下,NetDevPack.Security.Jwt将密钥存储在与ASP.NET Core存储其加密密钥材料相同的位置。它使用IXmlRepository

对DataProtection所做的任何更改也将适用于此。

你可以通过添加另一个提供程序并根据需要进行自定义来覆盖默认行为。

数据库

NetDevPack.Security.Jwt包提供了一种使用EntityFramework Core在数据库中存储密钥的方法。

通过NuGet包管理器安装:

    Install-Package NetDevPack.Security.Jwt.Store.EntityFrameworkCore

或通过.NET Core命令行界面:

    dotnet add package NetDevPack.Security.Jwt.Store.EntityFrameworkCore

ISecurityKeyContext添加到你的DbContext:

class MyKeysContext : DbContext, ISecurityKeyContext { public MyKeysContext(DbContextOptions<MyKeysContext> options) : base(options) { } // 这映射到存储密钥的表。 public DbSet<SecurityKeyWithPrivate> DataProtectionKeys { get; set; } }

然后在Startup.cs中更改你的配置

public void ConfigureServices(IServiceCollection services) { services.AddJwksManager().PersistKeysToDatabaseStore<MyKeysContext>(); }

完成!

文件系统

NetDevPack.Security.Jwt包提供了一种将密钥存储到文件系统的机制。

安装

    Install-Package NetDevPack.Security.Jwt.Store.FileSystem

或通过.NET Core命令行界面:

    dotnet add package NetDevPack.Security.Jwt.Store.FileSystem

现在更改你的startup.cs

public void ConfigureServices(IServiceCollection services) { services.AddJwksManager().PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys\")); }

示例

你可以在这里找到几个示例

更改算法

可以在配置过程中修改默认算法。

build.Services.AddJwksManager(o => { o.Jws = Algorithm.Create(DigitalSignaturesAlgorithm.RsaSsaPssSha256); o.Jwe = Algorithm.Create(EncryptionAlgorithmKey.RsaOAEP).WithContentEncryption(EncryptionAlgorithmContent.Aes128CbcHmacSha256); });

默认情况下,它使用根据RFC7518推荐的算法

build.Services.AddJwksManager(o => { o.Jws { get; set; } = Algorithm.Create(AlgorithmType.RSA, JwtType.Jws); o.Jwe { get; set; } = Algorithm.Create(AlgorithmType.RSA, JwtType.Jwe); }

Algorithm对象提供了多种选择。

Jws

算法:

简称名称
HS256Hmac Sha256
HS384Hmac Sha384
HS512Hmac Sha512
RS256Rsa Sha256
RS384Rsa Sha384
RS512Rsa Sha512
PS256Rsa SsaPss Sha256
PS384Rsa SsaPss Sha384
PS512Rsa SsaPss Sha512
ES256Ecdsa Sha256
ES384Ecdsa Sha384
ES512Ecdsa Sha512

Jwe

算法选项:

简称密钥管理算法
RSA1_5RSA1_5
RsaOAEPRSAES OAEP using
A128KWA128KW
A256KWA256KW

加密选项

简称内容加密算法
Aes128CbcHmacSha256A128CBC-HS256
Aes192CbcHmacSha384A192CBC-HS384
Aes256CbcHmacSha512A256CBC-HS512

IdentityServer4 - 自动jwks_uri管理

NetDevPack.Security.Jwt提供IdentityServer4密钥材料。它自动生成和轮换密钥。

首先安装

    Install-Package NetDevPack.Security.Jwt.IdentityServer4

或通过.NET Core命令行界面:

    dotnet add package NetDevPack.Security.Jwt.IdentityServer4

转到Startup.cs

public void ConfigureServices(IServiceCollection services) { var builder = services.AddIdentityServer() .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApis()) .AddInMemoryClients(Config.GetClients()); services.AddJwksManager().IdentityServer4AutoJwksManager(); }

如果你想使用数据库,请按照DatabaseStore的说明进行操作。

为什么

在使用OAuth 2.0或简单地签署JWT密钥开发应用程序和API时,支持各种算法。在这些算法中,一些被认为是最佳实践并优于其他算法,例如带有PS256算法的椭圆曲线。某些Auth服务器使用确定性算法运行,而其他服务器使用概率性算法。一些服务器,如Auth0,不支持多个JWK,但IdentityServer4支持你配置的任意数量。该组件旨在抽象这一层并为你的应用程序提供当前JWK管理的最佳实践。

负载均衡场景

在Kubernetes或Docker Swarm中使用容器时,扩展应用程序可能会导致某些问题,例如需要将DataProtection密钥存储在集中位置。虽然不建议绕过这种情况,但使用对称密钥是一种可能的解决方案。与DataProtection类似,该组件为你的JWKS提供了集中存储。

最佳实践

许多开发人员不确定应该使用哪种算法来签署他们的JWT。默认情况下,该组件使用带有ECDSA的椭圆曲线,利用P-256和SHA-256来帮助构建更安全的API和环境。它通过提供对最佳实践的更好理解并确保使用安全算法来简化JWKS管理。


许可证

NetDevPack.Security.Jwt是开源软件,根据MIT许可证发布。该许可证允许在自由和商业应用程序及库中无限制地使用NetDevPack.Security.Jwt。

编辑推荐精选

音述AI

音述AI

全球首个AI音乐社区

音述AI是全球首个AI音乐社区,致力让每个人都能用音乐表达自我。音述AI提供零门槛AI创作工具,独创GETI法则帮助用户精准定义音乐风格,AI润色功能支持自动优化作品质感。音述AI支持交流讨论、二次创作与价值变现。针对中文用户的语言习惯与文化背景进行专门优化,支持国风融合、C-pop等本土音乐标签,让技术更好地承载人文表达。

QoderWork

QoderWork

阿里Qoder团队推出的桌面端AI智能体

QoderWork 是阿里推出的本地优先桌面 AI 智能体,适配 macOS14+/Windows10+,以自然语言交互实现文件管理、数据分析、AI 视觉生成、浏览器自动化等办公任务,自主拆解执行复杂工作流,数据本地运行零上传,技能市场可无限扩展,是高效的 Agentic 生产力办公助手。

lynote.ai

lynote.ai

一站式搞定所有学习需求

不再被海量信息淹没,开始真正理解知识。Lynote 可摘要 YouTube 视频、PDF、文章等内容。即时创建笔记,检测 AI 内容并下载资料,将您的学习效率提升 10 倍。

AniShort

AniShort

为AI短剧协作而生

专为AI短剧协作而生的AniShort正式发布,深度重构AI短剧全流程生产模式,整合创意策划、制作执行、实时协作、在线审片、资产复用等全链路功能,独创无限画布、双轨并行工业化工作流与Ani智能体助手,集成多款主流AI大模型,破解素材零散、版本混乱、沟通低效等行业痛点,助力3人团队效率提升800%,打造标准化、可追溯的AI短剧量产体系,是AI短剧团队协同创作、提升制作效率的核心工具。

seedancetwo2.0

seedancetwo2.0

能听懂你表达的视频模型

Seedance two是基于seedance2.0的中国大模型,支持图像、视频、音频、文本四种模态输入,表达方式更丰富,生成也更可控。

nano-banana纳米香蕉中文站

nano-banana纳米香蕉中文站

国内直接访问,限时3折

输入简单文字,生成想要的图片,纳米香蕉中文站基于 Google 模型的 AI 图片生成网站,支持文字生图、图生图。官网价格限时3折活动

扣子-AI办公

扣子-AI办公

职场AI,就用扣子

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

堆友

堆友

多风格AI绘画神器

堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。

图像生成热门AI工具AI图像AI反应堆AI工具箱AI绘画GOAI艺术字堆友相机
码上飞

码上飞

零代码AI应用开发平台

零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

下拉加载更多