终极JavaScript对象签名和加密(JOSE),JSON Web令牌(JWT),JSON Web加密(JWE)和JSON Web键(JWK)实现.NET和.NET CORE
用于生成,解码和加密JSON Web令牌的最小零依赖性库。支持JSON Web算法和JSON Web键的完整套件。 JSON解析不可知论,可以插入任何所需的JSON处理库。对与Jose的兼容性进行了广泛的测试。4.J,Nimbus-Jose-Jwt和JSON-JWT库。 JWE JSON序列化与JWCrypto进行了交叉测试。
FIPS合规
由于v2.1,图书馆完全符合FIPS。
哪个版本?
-
v5.2.0释放,添加了.net6目标以删除对外部过时软件包的依赖关系
-
v5.1.1维护释放,改进的放气令牌的内存分配(请参阅#258,#257)
-
v5.1对实验算法RSA-OAEEP-384,RSA-OAEEP-512和强迫严格的AES-GCM的支持(请参阅dotnet/runtime#71366))
-
v5.0只要托管ECDSA键支持,就可以为ECDH加密带来Linux,OSX和FreeBSD兼容性。在NIST P-384,P-521曲线上解决了交叉兼容问题。并引入新的安全修复和控件。
-
v4.1添加了其他功能来管理运行时可用ALG套件,请参阅“安全性”库。并根据OWASP PBKDF2建议引入了PBKDF2(PBES2-*)最大迭代的默认最大限制。
-
v4.0引入了JSON Web密钥(JWK),RFC 7517支持。最新稳定。所有新功能很可能会根据给定版本出现。
-
v3.2删除newtonsoft.json支持支持system.text.json在netStandard2.1上
-
v3.1引入了RFC 7516中定义的JWE JSON序列化
-
v3.0及更高版本还针对NetStandard2.1,以更好地利用*NIX系统上的NET加密支持,并启用更多支持的算法。
-
v2.1及更高版本添加了.net461+的额外功能支持,并带有3个版本的二进制文件(Net4,Net461和NetStandard1.4)。
-
v2.0及更高版本是.NET Core兼容,旨在支持.NET框架(NET40)和.NET Core(NetStandard1.4)Runtimes。
-
V1.9仅针对.NET框架构建,应与Net40及更高版本兼容。除了关键的错误修复外,该版本不再积极维护。
-
WinRT兼容版本(Windows 8.1和Windows Phone 8.1)可以作为独立项目可用:Jose-rt。
-
居住在这里的基于PClcrypto的实验项目:Jose-PCL。
重要的升级笔记
配xV4-> V5 :
- JWK EC Keys现在默认桥接到ECDSA,而不是.NET 4.7.2+和NetStandard2.1+的CNGKEY
- jwk.tojson() / jwk.fromjson()现在默认为jwt.defaultsettings.jsonmapper,如果未明确提供。
- 默认情况下,放气解压缩限制为250kb。如果需要,请查看自定义部分。
配xv3.0-> v3.1更严格的参数验证extraheaders参数
在3.1及更高版本中,试图覆盖excem或the extheaders中的ALG标头值将引发参数置。
配xV2-> V3更新公共SDK更改
移动:
- security.cryptography.ecckey to jose.keys.ecckey
- security.cryptography.rsakey to jose.keys.rsakey
OS交叉兼容性
| .NET版本 | 视窗 | Linux | Mac OS | FreeBSD V14 |
|---|---|---|---|---|
| NetCoreApp2.1 | ✅ | ✅ | ||
| NetCoreApp3.1 | ✅ | ✅ | ✅ | |
| 净8.0 | ✅ | ✅ | ✅ | ✅ |
| 净5.0 | ✅ | ✅ | ✅ | |
| 净4.7 | ✅ | |||
| 净4.6 | ✅ | |||
| 净4.0 | ✅ |
前言
最初源自https://g*ithu*b.c*om/johnsheehan/jwt。几乎从头开始重新编写,以支持JWT加密功能和统一界面,用于编码/解码/加密和其他功能。 2014年2月搬到了单独的项目。
AES关键包装实现想法和测试数据来自http://www.crypt*o*f*reak.org/projects/rfc3394/ by Jay Miller
支持JWA算法
Clr
签名
- HMAC签名与HS256,HS384和HS512。
- ES256,ES384和ES512的ECDSA签名。
- RSASSA-PKCS1-V1_5签名,rs256,rs384和rs512。
- 带有PS256,PS384和PS512的RSASSA-PSS特征(带有附录的概率签名方案)。
- 无(无保护的)纯文本算法而没有完整性保护
加密
- RSAE OAEP 256,384,512(使用SHA-256,384,512和MGF1与SHA-256,384,512)与A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A192CBC-HS384,A28CBC-HS256,A256CBC-HS512,A12M6GM,A1128GCM,A192CBC-HS384,A192CBC-HS384
- RSAE OAEP(使用SHA-1和MGF1与SHA-1一起使用A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A128GCM,A192GCM,A256GCM,A256GCM,A256GCM
- RSAE-PKCS1-V1_5加密与A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A256GCM,A256GCM
- 使用预共享键A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A256GCM的直接对称密钥加密
- A128KW,A192KW,A256KW加密,A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A192GCM,A256GCM,A256GCM
- A128GCMKW,A192GCMKW,A256GCMKW加密A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A128GCM,A192GCM,A192GCM,A256GCM,A256GCM,A256GCM
- ECDH-ES *与A128CBC-HS256,A128GCM,A192GCM,A256GCM
- ECDH-ES+A128KW * ,ECDH-ES+A192KW * ,ECDH-ES+A256KW *与A128CBC-HS256,A128GCM,A192GCM,A256GCM,A256GCM
- PBES2-HS256+A128KW,PBES2-HS384+A192KW,PBES2-HS512+A256KW,带有A128CBC-HS256,A192CBC-HS384
压缩
- 放气压缩
Coreclr
签名
- HMAC签名与HS256,HS384和HS512。
- ES256,ES384和ES512的ECDSA签名。
- RSASSA-PKCS1-V1_5签名,rs256,rs384和rs512。
- 无(无保护的)纯文本算法而没有完整性保护
加密
- RSAE OAEP 256,384,512(使用SHA-256,384,512和MGF1与SHA-256,384,512)与A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A192CBC-HS384,A28CBC-HS256,A256CBC-HS512,A12M6GM,A1128GCM,A192CBC-HS384,A192CBC-HS384
- RSAE OAEP(使用SHA-1和MGF1与SHA-1一起使用A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A128GCM,A192GCM,A256GCM,A256GCM,A256GCM
- RSAE-PKCS1-V1_5加密与A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A256GCM,A256GCM
- 使用预共享键A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A256GCM的直接对称密钥加密
- A128KW,A192KW,A256KW加密,A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A192GCM,A192GCM,A256GCM,A256GCM
- A128GCMKW,A192GCMKW,A256GCMKW加密A128CBC-HS256,A192CBC-HS384,A256CBC-HS512,A128GCM,A128GCM,A192GCM,A192GCM,A256GCM,A256GCM,A256GCM
- PBES2-HS256+A128KW,PBES2-HS384+A192KW,PBES2-HS512+A256KW,带有A128CBC-HS256,A192CBC-HS384
- ECDH-ES *与A128CBC-HS256,A128GCM,A192GCM,A256GCM
- ECDH-ES+A128KW * ,ECDH-ES+A192KW * ,ECDH-ES+A256KW *与A128CBC-HS256,A128GCM,A192GCM,A256GCM,A256GCM
压缩
- 放气压缩
JSON Web键(JWK)
- RSA,EC,OCT键
- X509链,SHA1和SHA2指纹
笔记:
- Windows和Linux上的crytography方法返回的类型可能有所不同。例如,在 *nix上,Windows返回rsacng和opensslrsa上的x509certificate2上的getrsaprivatekey()。
- 看来Microsoft CNG的BcryptSecretagrement/ncryptSecretagreement的实现包含一个用于计算椭圆形曲线差异差异的错误,该键在高于256位的键上(P-384和P-521 NIST曲线)相应地相应地相应地高于256位(P-384和P-521 NIST曲线)。至少产生的秘密协议与不同语言的任何其他实现都不匹配。启动版5我们不建议使用ECDH-ES家族使用CNGKey键,因为与其他库的兼容性。请改用使用ECDSA,Ecdiffiehellman或JWK,它们在所有曲线和操作系统上都兼容。
安装
nuget
https://www.*nu*ge*t.org/packages/jose-jwt/
安装包装JOSE-JWT
手动的
抓住来源并编译自己:
- dotnet还原
- dotnet pack -c释放
用法
创建明文(未受保护的)令牌
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; string token = Jose . JWT . Encode ( payload , null , JwsAlgorithm . none ) ;
警告:将类用作有效载荷的数据结构时,请始终使用无效的数据类型作为其属性。细节
创建签名的令牌
HS-*家庭
HS256,HS384,HS512签名需要字节[]数组键或JWK类型的相应长度的OCT类型键
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var secretKey = new byte [ ] { 164 , 60 , 194 , 0 , 161 , 189 , 41 , 38 , 130 , 89 , 141 , 164 , 45 , 170 , 159 , 209 , 69 , 137 , 243 , 216 , 191 , 131 , 47 , 250 , 32 , 107 , 231 , 117 , 37 , 158 , 225 , 234 } ; string token = Jose . JWT . Encode ( payload , secretKey , JwsAlgorithm . HS256 ) ;
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; Jwk key = new Jwk ( new byte [ ] { 164 , 60 , 194 , 0 , 161 , 189 , 41 , 38 , 130 , 89 , 141 , 164 , 45 , 170 , 159 , 209 , 69 , 137 , 243 , 216 , 191 , 131 , 47 , 250 , 32 , 107 , 231 , 117 , 37 , 158 , 225 , 234 } ) ; string token = Jose . JWT . Encode ( payload , key , JwsAlgorithm . HS256 ) ;
rs-*和ps-*家庭
net40-net45 :
RS256,RS384,RS512和PS256,PS384,PS512签名需要相应长度的rsacryptoserviceProvider(通常是私有)密钥。 CSP需要被迫使用Microsoft增强的RSA和AES加密提供商。通常可以这样做是重新体现的rsaparameters。有关详细信息,请参见http://clrsecurity.c***odeplex.com/discussions/243156。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var privateKey = new X509Certificate2 ( \"my-key.p12\" , \"password\" , X509KeyStorageFlags . Exportable | X509KeyStorageFlags . MachineKeySet ) . PrivateKey as RSACryptoServiceProvider ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . RS256 ) ;
NetCore :RS256,RS384,RS512和PS256,PS384,PS512签名需要RSA(通常是私有)或JWK相应长度的RSA类型的JWK键。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var privateKey = new X509Certificate2 ( \"my-key.p12\" , \"password\" ) . GetRSAPrivateKey ( ) ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . RS256 ) ;
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; Jwk privateKey = new Jwk ( e : \"AQAB\" , n : \"qFZv0pea_jn5Mo4qEUmStuhlulso8n1inXbEotd_zTrQp9K0RK0hf7t0K4BjKVhaiqIam4tVVQvkmYeBeYr1MmnO_0N97dMBz_7fmvyv0hgHaBdQ5mR5u3LTlHo8tjRE7-GzZmGs6jMcyj7HbXobDPQJZpqNy6JjliDVXxW8nWJDetxGBlqmTj1E1fr2RCsZLreDOPSDIedG1upz9RraShsIDzeefOcKibcAaKeeVI3rkAU8_mOauLSXv37hlk0h6sStJb3qZQXyOUkVkjXIkhvNu_ve0v7LiLT4G_OxYGzpOQcCnimKdojzNP6GtVDaMPh-QkSJE32UCos9R3wI2Q\" , p : \"0qaOkT174vRG3E_67gU3lgOgoT6L3pVHuu7wfrIEoxycPa5_mZVG54SgvQUofGUYEGjR0lavUAjClw9tOzcODHX8RAxkuDntAFntBxgRM-IzAy8QzeRl_cbhgVjBTAhBcxg-3VySv5GdxFyrQaIo8Oy_PPI1L4EFKZHmicBd3ts\" , q : \"zJPqCDKqaJH9TAGfzt6b4aNt9fpirEcdpAF1bCedFfQmUZM0LG3rMtOAIhjEXgADt5GB8ZNK3BQl8BJyMmKs57oKmbVcODERCtPqjECXXsxH-az9nzxatPvcb7imFW8OlWslwr4IIRKdEjzEYs4syQJz7k2ktqOpYI5_UfYnw1s\" , d : \"lJhwb0pKlB2ivyDFO6thajotClrMA3nxIiSkIUbvVr-TToFtha36gyF6w6e6YNXQXs4HhMRy1_b-nRQDk8G4_f5urd_q-pOn5u4KfmqN3Xw-lYD3ddi9qF0NLeTVUNVFASeP0FFqbPYfdNwD-LyvwjhtT_ggMOAw3mYvU5cBfz6-3uPdhl3CwQFCTgwOud_BA9p2MPMUHG82wMK_sNO1I0TYpjm7TnwNBwiKbMf-i5CKnuohgoYrEDYLeMg3f32eBljlCFNYaoCtT-mr1Ze0OTJND04vbfLotV-BBKulIpbOOSeVpKG7gJxZHmv7in7PE5_WzaxKFVoHW3wR6v_GzQ\" , dp : \"KTWmTGmf092AA1euOmRQ5IsfIIxQ5qGDn-FgsRh4acSOGE8L7WrTrTU4EOJyciuA0qz-50xIDbs4_j5pWx1BJVTrnhBin9vNLrVo9mtR6jmFS0ko226kOUpwEVLgtdQjobWLjtiuaMW-_Iw4gKWNptxZ6T1lBD8UWHaPiEFW2-M\" , dq : \"Jn0lqMkvemENEMG1eUw0c601wPOMoPD4SKTlnKWPTlQS6YISbNF5UKSuFLwoJa9HA8BifDrD-Mfpo1M1HPmnoilEWUrfwMqqdCkOlbiJQhKY8AZ16QGH50kDXhmVVa8BRWdVQWBTUzWXS5kXMaeskVzextTgymPcOAhXN-ph7MU\" , qi : \"sRAPigJpl8S_vsf1zhJTrHM97xRwuB26R6Tm-J8sKRPb7p5xxNlmOBBFvWmWxdto8dBElNlydSZan373yBLxzW-bZgVp-B2RKT1B3WhTYW_Vo5DLhWi84XMncJxH7avtxtF9yksaeKe0e2n3J6TTan53mDg4KF8U0OEO2ciqO9g\" ) ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . RS256 ) ;
NET461及以上:接受rsacryptoserviceProvider,RSA或JWK类型的键(请参见上文)。
es-*家庭
net40-net45 :ES256,ES384,ES512 ECDSA签名需要cngkey(通常是私有)椭圆曲线相应长度的关键。通常通过cngkey加载的现有cngkey从密钥存储提供商加载(..)方法。但是,如果您想使用原始钥匙材料(X,Y)和D,Jose-JWT提供了方便的助手ecckey.new(x,y,d)。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; byte [ ] x = { 4 , 114 , 29 , 223 , 58 , 3 , 191 , 170 , 67 , 128 , 229 , 33 , 242 , 178 , 157 , 150 , 133 , 25 , 209 , 139 , 166 , 69 , 55 , 26 , 84 , 48 , 169 , 165 , 67 , 232 , 98 , 9 } ; byte [ ] y = { 131 , 116 , 8 , 14 , 22 , 150 , 18 , 75 , 24 , 181 , 159 , 78 , 90 , 51 , 71 , 159 , 214 , 186 , 250 , 47 , 207 , 246 , 142 , 127 , 54 , 183 , 72 , 72 , 253 , 21 , 88 , 53 } ; byte [ ] d = { 42 , 148 , 231 , 48 , 225 , 196 , 166 , 201 , 23 , 190 , 229 , 199 , 20 , 39 , 226 , 70 , 209 , 148 , 29 , 70 , 125 , 14 , 174 , 66 , 9 , 198 , 80 , 251 , 95 , 107 , 98 , 206 } ; var privateKey = EccKey . New ( x , y , d ) ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . ES256 ) ;
NetCore :ES256,ES384,ES512 ECDSA签名可以接受CNGKEY(请参见上文),ECDSA(通常是私有)或类型EC椭圆曲线的JWK,相应长度的eLpiptic曲线键。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var privateKey = new X509Certificate2 ( \"ecc-key.p12\" , \"password\" ) . GetECDsaPrivateKey ( ) ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . ES256 ) ;
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var privateKey = new Jwk ( crv : \"P-256\" , x : \"BHId3zoDv6pDgOUh8rKdloUZ0YumRTcaVDCppUPoYgk\" , y : \"g3QIDhaWEksYtZ9OWjNHn9a6-i_P9o5_NrdISP0VWDU\" , d : \"KpTnMOHEpskXvuXHFCfiRtGUHUZ9Dq5CCcZQ-19rYs4\" ) ; string token = Jose . JWT . Encode ( payload , privateKey , JwsAlgorithm . ES256 ) ;
Net461及以上:接受CNGKEY,ECDSA和JWK类型的键(请参见上文)。
创建加密的令牌
RSA-*关键算法管理家庭
net40-net45 :
RSA-OAEP-256,RSA-OAEEP-384,RSA-OAEP-512,RSA-OAEP和RSA1_5密钥管理需要RSACRYPTOSERVICEPROVIDER(通常是公共)相应长度的密钥。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var publicKey = new X509Certificate2 ( \"my-key.p12\" , \"password\" ) . PublicKey . Key as RSACryptoServiceProvider ; string token = Jose . JWT . Encode ( payload , publicKey , JweAlgorithm . RSA_OAEP , JweEncryption . A256GCM ) ;
NetCore: RSA-OAEP-256,RSA-OAEP-384,RSA-OAEEP-512,RSA-OAEEP和RSA1_5密钥管理需要RSA(通常是公共)或JWK相应长度的RSA类型的JWK密钥。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var publicKey = new X509Certificate2 ( \"my-key.p12\" , \"password\" ) . GetRSAPublicKey ( ) ; string token = Jose . JWT . Encode ( payload , publicKey , JweAlgorithm . RSA_OAEP , JweEncryption . A256GCM ) ;
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; Jwk publicKey = new Jwk ( \"AQAB\" , \"qFZv0pea_jn5Mo4qEUmStuhlulso8n1inXbEotd_zTrQp9K0RK0hf7t0K4BjKVhaiqIam4tVVQvkmYeBeYr1MmnO_0N97dMBz_7fmvyv0hgHaBdQ5mR5u3LTlHo8tjRE7-GzZmGs6jMcyj7HbXobDPQJZpqNy6JjliDVXxW8nWJDetxGBlqmTj1E1fr2RCsZLreDOPSDIedG1upz9RraShsIDzeefOcKibcAaKeeVI3rkAU8_mOauLSXv37hlk0h6sStJb3qZQXyOUkVkjXIkhvNu_ve0v7LiLT4G_OxYGzpOQcCnimKdojzNP6GtVDaMPh-QkSJE32UCos9R3wI2Q\" ) ; string token = Jose . JWT . Encode ( payload , publicKey , JweAlgorithm . RSA_OAEP , JweEncryption . A256GCM ) ;
NET461 :接受rsacryptoserviceProvider,RSA,JWK(请参见上文)和键的CNGKEY类型。
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; CngKey publicKey = CngKey . Open ( \"connectionKeyId\" , CngProvider . MicrosoftSoftwareKeyStorageProvider , CngKeyOpenOptions . MachineKey ) ) ; string token = Jose . JWT . Encode ( payload , publicKey , JweAlgorithm . RSA_OAEP , JweEncryption . A256GCM ) ;
DIR直接共享对称的算法家族
带有预共享对称键的直接密钥管理需要字节[]阵列或类型oct oct键的相应长度键
var payload = new Dictionary < string , object > ( ) { { \"sub\" , \"mr.x@contoso.com\" } , { \"exp\" , 1300819380 } } ; var secretKey = new byte [ ] { 164 , 60 , 194 , 0 , 161 , 189 , 41 , 38 , 130 , 89 , 141 , 164 , 45 , 170 , 159 , 209 , 69 , 137 , 243 , 216 , 191 , 131 , 47 , 250 , 32 , 107 , 231 , 117 , 37 , 158 , 225 , 234 } ; string token = Jose . JWT .
