如何加密JWT安全令牌?

我需要通过签名和加密来保护我的网络令牌。 我编写了下一行代码:

var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, owner.Name), new Claim(ClaimTypes.Role, owner.RoleClaimType), new Claim("custom claim type", "custom content") }), TokenIssuerName = "self", AppliesToAddress = "http://www.example.com", Lifetime = new Lifetime(now, now.AddSeconds(60 * 3)), EncryptingCredentials = new X509EncryptingCredentials(new X509Certificate2(cert)), SigningCredentials = new X509SigningCredentials(cert1) }; var token = (JwtSecurityToken)tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); 

所以,我正在使用一些使用makecert.exe生成的证书。 然后我用另一个JwtSecurityTokenHandler读取令牌字符串:

 var tokenHandlerDecr = new JwtSecurityTokenHandler(); var tok = tokenHandlerDecr.ReadToken(tokenString); 

并且令牌内容未加密(我可以在调试器下看到tok变量中的json)。 我究竟做错了什么? 如何加密令牌数据?

我的理解是,微软的JWT实现目前不支持加密(仅签名)。

我知道这是一个很老的post,但是如果有人还在寻找答案,我会添加我的答案。

Microsoft.IdentityModel.Tokens版本5.1.3中解决了此问题。 CreateJwtSecurityToken函数中有一个重载方法,它接受加密凭据来加密令牌。

如果接收方未validation签名并尝试按原样读取JWT,则声明为空。 以下是代码段:

 using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; const string sec = "ProEMLh5e_qnzdNUQrqdHPgp"; const string sec1 = "ProEMLh5e_qnzdNU"; var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec)); var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1)); var signingCredentials = new SigningCredentials( securityKey, SecurityAlgorithms.HmacSha512); List claims = new List() { new Claim("sub", "test"), }; var ep = new EncryptingCredentials( securityKey1, SecurityAlgorithms.Aes128KW, SecurityAlgorithms.Aes128CbcHmacSha256); var handler = new JwtSecurityTokenHandler(); var jwtSecurityToken = handler.CreateJwtSecurityToken( "issuer", "Audience", new ClaimsIdentity(claims), DateTime.Now, DateTime.Now.AddHours(1), DateTime.Now, signingCredentials, ep); string tokenString = handler.WriteToken(jwtSecurityToken); // Id someone tries to view the JWT without validating/decrypting the token, // then no claims are retrieved and the token is safe guarded. var jwt = new JwtSecurityToken(tokenString); 

以下是validation/解密令牌的代码:

 using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; const string sec = "ProEMLh5e_qnzdNUQrqdHPgp"; const string sec1 = "ProEMLh5e_qnzdNU"; var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec)); var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1)); // This is the input JWT which we want to validate. string tokenString = string.Empty; // If we retrieve the token without decrypting the claims, we won't get any claims // DO not use this jwt variable var jwt = new JwtSecurityToken(tokenString); // Verification var tokenValidationParameters = new TokenValidationParameters() { ValidAudiences = new string[] { "536481524875-glk7nibpj1q9c4184d4n3gittrt8q3mn.apps.googleusercontent.com" }, ValidIssuers = new string[] { "https://accounts.google.com" }, IssuerSigningKey = securityKey, // This is the decryption key TokenDecryptionKey = securityKey1 }; SecurityToken validatedToken; var handler = new JwtSecurityTokenHandler(); handler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken);