asp.net core jwe

asp.net core jwe 实践


1,概括
从原理上来说jwt实现的身份认证,实际上就是加密解密的过程放到http请求中的一个过程,服务端将特定信息加密,编码后返回给客户端,客户端在请求的过程中将这段经过加密编码的信息放到请求头中,服务端在收到请求的时候,根据头信息特定字段来判断该请求的来源是否是本站点的正常请求,所对应的系统用户等.所以从这个角度看jwt是分为两部分的,第一部分是加密编码生成串,第二部分就是验证.在实际工程中一般也会涉及到续期,什么时机要对客户端的jwt串传出即将过期指令,什么时机客户端用新的jwt串来执行新请求,是一个工程问题,解决方式不只一种,如何做取决于实际情况,当然还会涉及到token过期,信息安全等等一系列问题,本文将针对jwt使用过程中的所有问题展开讨论,给出一个安全可靠的jwt实践方案.

2,jwt是什么
JWT定义
​datatracker.ietf.org/doc/html/rfc7519
JSON Web Token (JWT) 是一种紧凑的、URL 安全的表示方式
要求在两方之间转让。JWT 中的声明
被编码为 JSON 对象,用作 JSON 的有效负载
Web 签名 (JWS) 结构或作为 JSON Web 的明文
加密 (JWE) 结构,使声明能够数字化
使用消息验证码进行签名或完整性保护
(MAC) 和/或加密。
定义如上, http://jwt.io中有一个在线的jwt调试器,后边内容有多处会用到jwt调试器来验证我们的jwt实现.

jwt 的

3.信息安全版JWE
基础版中的实现里有对jwt来源签名的验签过程,但是放在Claims中的信息并不安全,打开jwt.io,输入请求中拿到的jwt串

这里 可以很清楚的看到我们Claims的信息,这样的话,只要别人知道签名的key就能伪造签名,即便说一般获取不了签名,别人可以看到系统中的一些机密信息也是很不好的体验.下边就这个问题,用对称加密和非对称加密两种方式对信息进行加密.

1,对称加密+签名

using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;

 namespace Hero.Jwt
 {
  public class Jwt : IJwt
    {
        private readonly JwtConfig _jwtConfig = new JwtConfig();
        private byte[] signingKey;
        private byte[] encKey=new byte[32];
        public Jwt(IConfiguration configration)
        {
            configration.GetSection("Jwt").Bind(_jwtConfig);
            GenrateSigningKey();
        }
   
    /// <summary>
    /// 生成签名
    /// 需要用到512位固定长度签名,所以这里用签名算法做是最为稳妥的.
    /// </summary>
  
 private void GenrateSigningKey()
  {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(_jwtConfig.SecretKey);
        byte[] messageBytes = encoding.GetBytes(_jwtConfig.SecretKey);
        using (HMACSHA512 hmacsha512 = new HMACSHA512(keyByte))
        {
            signingKey = hmacsha512.ComputeHash(messageBytes);
            Buffer.BlockCopy(signingKey, 10, encKey, 0, encKey.Length);
        }
    }


   /// <summary>
    /// 生成JWE Token
    /// </summary>
public string GetToken(IDictionary<string, object> Claims)
    {
	    byte[] signingKey;
        byte[] encKey=new byte[32];
        
        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
        SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
        {
            Issuer = _jwtConfig.Issuer,
            Audience = _jwtConfig.Audience,
            NotBefore = DateTime.Now,
            Expires = DateTime.Now.AddMinutes(_jwtConfig.Lifetime),
            Claims =Claims,
            
            //对称加密
            SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(signingKey), 
            SecurityAlgorithms.HmacSha512),
            
            EncryptingCredentials = new EncryptingCredentials(
            new SymmetricSecurityKey(encKey), 
            SecurityAlgorithms.Aes256KW, 
            SecurityAlgorithms.Aes256CbcHmacSha512)
        };
        
        SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(securityToken);
    }

.

    public bool ValidateToken(string Token, out Dictionary<string, object> Clims)
    {
        Clims = new Dictionary<string, object>();
        ClaimsPrincipal principal = null;
        if (string.IsNullOrWhiteSpace(Token))
        {
            return false;
        }
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
        try
        {
            JwtSecurityToken jwt = handler.ReadJwtToken(Token);
            if (jwt == null)
            {
                return false;
            }
            TokenValidationParameters validationParameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                ClockSkew = TimeSpan.Zero,
                IssuerSigningKey = new SymmetricSecurityKey(signingKey),
                TokenDecryptionKey = new SymmetricSecurityKey(encKey),
                ValidateIssuer = true,//是否验证Issuer
                ValidateAudience = true,//是否验证Audience
                ValidateLifetime = _jwtConfig.ValidateLifetime,//是否验证失效时间
                ValidAudience = _jwtConfig.Audience,
                ValidIssuer = _jwtConfig.Issuer,
                ValidateIssuerSigningKey = true,//是否验证签名
            };
            principal = handler.ValidateToken(Token, validationParameters, out SecurityToken securityToken);
            foreach (Claim item in principal.Claims)
            {
                Clims.Add(item.Type, item.Value);
            }
            return true;
        }
        catch (SecurityTokenInvalidLifetimeException ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }
}

}

2,非对称加密+签名

using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;

namespace Hero.Jwt
{
public class Jwt : IJwt
{
    private readonly JwtConfig _jwtConfig = new JwtConfig();
    private byte[] signingKey;
    private byte[] encKey=new byte[32];
    public Jwt(IConfiguration configration)
    {
        configration.GetSection("Jwt").Bind(_jwtConfig);
        GenrateSigningKey();
    }
    /// <summary>
    /// 生成签名
    /// 需要用到512位固定长度签名,所以这里用签名算法做是最为稳妥的.
    /// </summary>
    private void GenrateSigningKey()
    {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(_jwtConfig.SecretKey);
        byte[] messageBytes = encoding.GetBytes(_jwtConfig.SecretKey);
        using (HMACSHA512 hmacsha512 = new HMACSHA512(keyByte))
        {
            signingKey = hmacsha512.ComputeHash(messageBytes);
            Buffer.BlockCopy(signingKey, 10, encKey, 0, encKey.Length);
        }
    }
    /// <summary>
    /// 生成Token
    /// </summary>
    /// <param name="Claims"></param>
    /// <returns></returns>
    public string GetToken(IDictionary<string, object> Claims)
    {
        string pubkeySigning = "MIIBCgKCAQEAuyeviRRcsPGxSUyYnhE8zYFquUc4InAa5K4qw5Y43R/1sm5jWZiG670+aq+y/1Ovx4RXlyBpzwo4ws0FB7YZyPIPRiZZbB9oIeNd19fdPu7U70lSaIfh9TjHW9Kjb40YFnxm6nltY7QXTw2VeISVZApD0DcL8TieD3cgGpKJjo4nhaHNFmRLR80mSOjFrKFoun5iLk1azljHEpVjqVotKF+5o80DzxW7EywoS2YuXYMI7tOIPP33cRLMFxokZSy2BFeeuu4jakDsvTxMaipOCyumbE2/Fd7bo59n1/jgfyP11rR8HtkhdS9SbK0nw6rVEddFxym6TKjczrxIYxuR4QIDAQAB";
        string prikeySigning = "MIIEogIBAAKCAQEAuyeviRRcsPGxSUyYnhE8zYFquUc4InAa5K4qw5Y43R/1sm5jWZiG670+aq+y/1Ovx4RXlyBpzwo4ws0FB7YZyPIPRiZZbB9oIeNd19fdPu7U70lSaIfh9TjHW9Kjb40YFnxm6nltY7QXTw2VeISVZApD0DcL8TieD3cgGpKJjo4nhaHNFmRLR80mSOjFrKFoun5iLk1azljHEpVjqVotKF+5o80DzxW7EywoS2YuXYMI7tOIPP33cRLMFxokZSy2BFeeuu4jakDsvTxMaipOCyumbE2/Fd7bo59n1/jgfyP11rR8HtkhdS9SbK0nw6rVEddFxym6TKjczrxIYxuR4QIDAQABAoIBAHAnCwjhW95pJ61eKkLm34HjIPpglGIGvgb13AiS+AaCxXCkuAKT5Z5VLJcwLNrW4op0YyzcLqv0WylZRL9nP7JsY/zMtF+XvoY4Qx86a4nwA0hVrv2XGDAkU0tSQcByU9H9wIqYM5ZA8IreAAlVolRt1k9q/UwTepyX7XQfBjGXNft0qu3A3gLIpzVn/oH5mD4UNsNDdgJ/s4FebvdGSucM/UWBoDP4TaotN1IV8yBNyFJhBWMkbRLs20dbfgiFqDnRF8+69Ylw6qrokHDZwZRB5/NMiFt+UFmCFc3RbSps2L1tWLOdAQ5MPTELn+1kk26jkcHP7cZXVbOzqHKQkTUCgYEA2LkujXIdOY1LeB5bSkPUND8PtmVgrsiAEfP/nWX629+UIqwwGtGJz9Gt5c3CNvIsGzazHaUE4DI5ru4B+HgU45ifbLMtII5AtdY8oPd0nTwHpF6iSYKmJzPFPdordyxZ36CLzhaVI9mdHRJS84Fj5O1DJ548PANLz5rTLDiJEbsCgYEA3RKwY636eo3sIjHVHTe3gOt+s3Q41P+Lh1v9TiEuZthg3f7tZUY2EQileLxNAjgAK48XMbtgRTLNax688WjjLIQaYQyXl074gJ1Hn/dirNOGQMrYgrxXmM5oBgXqmEA321W9hz9k7JRYw7HqjKSL2+h8GeacXfkFyC9YZiFFMxMCgYBdNhBSn6D4LtAlwpCq+U9chT7hyOpzYiLLFfF7pe/l/1w8KWirMDIgouMzMnL0pOXZcoZJGr9lGdT7aryIPEVnui3fV5TyKpykWJdM+AE82yPCSz1rdni15atQtfP51qZ06x0WL1pHyAGuDkKFHsJzJKS8dm8btKM3kDSBEXPKnwKBgG8bt39Br4Ps1GMTPJLkr9uhgBpdLTsP/GZZe2PLFXEnCvhH6bRep0nEWLXnnaSh1KQP1I5wKCBfOhK+biO+nX6AHmnsVDv9urOZWKgzQ2qtHOpviIWcd0Ibavir/I3sqKYZ35mb6PNmU353avSotoodvFGgL7KjN562/OzHh+n1AoGAFBFnvge50H2FTT2MlKZ53yY27OAuKK2+KUQGK8OIP4fSWvisFzA68cQrejyAxkx4JMMic0OnHgLMi75Noz6aUYDdtRmuzkmxugz96bhFuj1UhH3HqqaLwn8yrw68X4dUD6eSv7sBhL9RJTVz3cuaR1wFaXZfEhfVcdRlvDYfa0k=";
        string pubkeyEncrypt = "MIIBCgKCAQEAxKrM4LqoQ7O37Wiybx/80NUwi9dDc+hP5MWx/uAyaoWsCTE3AXTcANqKR4MWd8FDKpyJn9WrIDaRnl4XuW8992Bpzqo4KbHlefQ6z848ox7M8BCqyiQ0uz5FeezFzhe1FBGpRmw1o1rH3mpjnkjpb81wWY6NyI6k7/ZUIQFX5Sn8g4vnaGNBlnhhd3oh8esM2IhoDcPvK2QXnpCa1o+md7O3VM1J1M2jIVvULaE5dxz2NIUCQnxFCgH/XYKfcEZEwjBubkFK2HP+pPKo0ZX9kfQ2MPOj7l04YTikA2Majym3BL38U/bNSt8rYHg5EIWwwObYxlo6NOWQRFYM9c1fZQIDAQAB";
        string prikeyEncrypt = "MIIEpAIBAAKCAQEAxKrM4LqoQ7O37Wiybx/80NUwi9dDc+hP5MWx/uAyaoWsCTE3AXTcANqKR4MWd8FDKpyJn9WrIDaRnl4XuW8992Bpzqo4KbHlefQ6z848ox7M8BCqyiQ0uz5FeezFzhe1FBGpRmw1o1rH3mpjnkjpb81wWY6NyI6k7/ZUIQFX5Sn8g4vnaGNBlnhhd3oh8esM2IhoDcPvK2QXnpCa1o+md7O3VM1J1M2jIVvULaE5dxz2NIUCQnxFCgH/XYKfcEZEwjBubkFK2HP+pPKo0ZX9kfQ2MPOj7l04YTikA2Majym3BL38U/bNSt8rYHg5EIWwwObYxlo6NOWQRFYM9c1fZQIDAQABAoIBACr8vn2cryzlOp3NFbuOfV9USiE280qBi/0QbWCttrdr8ner5z8NQQ16t2D8OUwB1WGaB8cFGDuZUekQ3hStSRkqXNZMhKwwc11d0gEcLkrlb5xFuF8o3NHUwbDt3Sq4Kd9yINMA0hSbwjZOgOnXPBcxC463xywAafL9n9P7DDBNw17l2ykW7gJtNRy6tf2kjCEfnHEIgXZZ19xp/BfApYAcLb/v9C/tRaWAzWLLTwX9GEOrJ2XjzIUOrdCmdO85VbH3b2bGHWwi2orbD+uvCZOPcCsOyQjUme40JaDQwgkCPTh/9F5/u/Z8sVcCw/mgzoaxWImdCwwQCj49FhT52V0CgYEA/CEL1VlL5Gb2tolhG8hufORzu2Id0uDNKsUZd92hM4Y98tyDnCqE/F3jiv63G0utHSzC3Rt77iiX9LXXV3AP/Zz91LNEm/vICSEeDOFejx7XEsnjsJuoDMZPt+bNu4bFWv0j81fuVyZ9ZPoy4xb+abmkebq9F2QxvcQs2DO+SKMCgYEAx6/FEaGKk10XWCdFEBeI3I3GViDYzSBEEnaI+wSR7VPBZkCt0w2aD4/wrw3pmlTAkN882GDdFzojtEd7t2nXgp03S0F5T5aGD4pFZWaqUYqz/bQ/UxBp0C5qHR084J5XarllTPBzbZ0fo1eY1Cde/mj/TD722o+9hUsmbi0NkFcCgYEAsZRY8FCvmlRG6jQCeH4IC+Ef/lfR56g7+SbPlFQ+aLrhQP+9lq1/8vvx+wECWLBJYqYXLYJhHFHtDQdSf5xHNvpu8XO+HBsPPhbcQngtkKJJG0ulGcvYZf77QOzH9I+syzRGMOu6zBko8okidD3KvQ5q4O38ptAEFMNqTnDLUf8CgYB6k/VfG1DboRuBa6nDdQ74hLcpi8RKNvJSex0fKfECRJXF1RJfKkxWHT/b1ah+qmQDCmZpVRyi83eTZQYW0wwOC8AznB+BsZ7dzz1GP71xjLlslccBkGPD/Zn6AUarg8eZpfD/R+MzeG5BcLZKFVkExyNghI44IGBwgG841sMqxQKBgQD6nSV5kw8RXBlzWfjI/q9hU0f9U4E2ZX66iNrUhlmK12yDXd0l3I4vpffo2HQVHRGP+4LKnX7g+7P6Zrs3GHoOg7EbnYjcReoBNoxwgTx93b6qBEi9yfQNYVPgZIwxMYq62yNlTcAp9CQLAwkOWaTO51viAVICUOmbQelIny9cMA==";
        RSA rsaSigning = RSA.Create();
        //rsaSigning.ExportRSAPrivateKey() 生成私钥
        //rsaSigning.ExportRSAPublicKey() 生成公钥
        rsaSigning.ImportRSAPrivateKey(Convert.FromBase64String(prikeySigning), out int bytesread);
        RSA rsaEncrypt = RSA.Create();
        rsaEncrypt.ImportRSAPublicKey(Convert.FromBase64String(pubkeyEncrypt), out int bytesread1);
        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
        SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
        {
            Issuer = _jwtConfig.Issuer,
            Audience = _jwtConfig.Audience,
            NotBefore = DateTime.Now,
            Expires = DateTime.Now.AddMinutes(_jwtConfig.Lifetime),
            Claims =Claims,
            //SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(signingKey), SecurityAlgorithms.HmacSha512),//对称加密
            //EncryptingCredentials = new EncryptingCredentials(new SymmetricSecurityKey(encKey), SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512)
            SigningCredentials = new SigningCredentials(new RsaSecurityKey(rsaSigning.ExportParameters(true)), SecurityAlgorithms.RsaSsaPssSha512),//非对称私钥签名,公钥验签
            EncryptingCredentials = new EncryptingCredentials(new RsaSecurityKey(rsaEncrypt.ExportParameters(false)), SecurityAlgorithms.RsaOAEP, SecurityAlgorithms.Aes128CbcHmacSha256)//非对称加密
            
        };
        SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(securityToken);
    }

    public bool ValidateToken(string Token, out Dictionary<string, object> Clims)
    {
        string pubkeySigning = "MIIBCgKCAQEAuyeviRRcsPGxSUyYnhE8zYFquUc4InAa5K4qw5Y43R/1sm5jWZiG670+aq+y/1Ovx4RXlyBpzwo4ws0FB7YZyPIPRiZZbB9oIeNd19fdPu7U70lSaIfh9TjHW9Kjb40YFnxm6nltY7QXTw2VeISVZApD0DcL8TieD3cgGpKJjo4nhaHNFmRLR80mSOjFrKFoun5iLk1azljHEpVjqVotKF+5o80DzxW7EywoS2YuXYMI7tOIPP33cRLMFxokZSy2BFeeuu4jakDsvTxMaipOCyumbE2/Fd7bo59n1/jgfyP11rR8HtkhdS9SbK0nw6rVEddFxym6TKjczrxIYxuR4QIDAQAB";
        string prikeySigning = "MIIEogIBAAKCAQEAuyeviRRcsPGxSUyYnhE8zYFquUc4InAa5K4qw5Y43R/1sm5jWZiG670+aq+y/1Ovx4RXlyBpzwo4ws0FB7YZyPIPRiZZbB9oIeNd19fdPu7U70lSaIfh9TjHW9Kjb40YFnxm6nltY7QXTw2VeISVZApD0DcL8TieD3cgGpKJjo4nhaHNFmRLR80mSOjFrKFoun5iLk1azljHEpVjqVotKF+5o80DzxW7EywoS2YuXYMI7tOIPP33cRLMFxokZSy2BFeeuu4jakDsvTxMaipOCyumbE2/Fd7bo59n1/jgfyP11rR8HtkhdS9SbK0nw6rVEddFxym6TKjczrxIYxuR4QIDAQABAoIBAHAnCwjhW95pJ61eKkLm34HjIPpglGIGvgb13AiS+AaCxXCkuAKT5Z5VLJcwLNrW4op0YyzcLqv0WylZRL9nP7JsY/zMtF+XvoY4Qx86a4nwA0hVrv2XGDAkU0tSQcByU9H9wIqYM5ZA8IreAAlVolRt1k9q/UwTepyX7XQfBjGXNft0qu3A3gLIpzVn/oH5mD4UNsNDdgJ/s4FebvdGSucM/UWBoDP4TaotN1IV8yBNyFJhBWMkbRLs20dbfgiFqDnRF8+69Ylw6qrokHDZwZRB5/NMiFt+UFmCFc3RbSps2L1tWLOdAQ5MPTELn+1kk26jkcHP7cZXVbOzqHKQkTUCgYEA2LkujXIdOY1LeB5bSkPUND8PtmVgrsiAEfP/nWX629+UIqwwGtGJz9Gt5c3CNvIsGzazHaUE4DI5ru4B+HgU45ifbLMtII5AtdY8oPd0nTwHpF6iSYKmJzPFPdordyxZ36CLzhaVI9mdHRJS84Fj5O1DJ548PANLz5rTLDiJEbsCgYEA3RKwY636eo3sIjHVHTe3gOt+s3Q41P+Lh1v9TiEuZthg3f7tZUY2EQileLxNAjgAK48XMbtgRTLNax688WjjLIQaYQyXl074gJ1Hn/dirNOGQMrYgrxXmM5oBgXqmEA321W9hz9k7JRYw7HqjKSL2+h8GeacXfkFyC9YZiFFMxMCgYBdNhBSn6D4LtAlwpCq+U9chT7hyOpzYiLLFfF7pe/l/1w8KWirMDIgouMzMnL0pOXZcoZJGr9lGdT7aryIPEVnui3fV5TyKpykWJdM+AE82yPCSz1rdni15atQtfP51qZ06x0WL1pHyAGuDkKFHsJzJKS8dm8btKM3kDSBEXPKnwKBgG8bt39Br4Ps1GMTPJLkr9uhgBpdLTsP/GZZe2PLFXEnCvhH6bRep0nEWLXnnaSh1KQP1I5wKCBfOhK+biO+nX6AHmnsVDv9urOZWKgzQ2qtHOpviIWcd0Ibavir/I3sqKYZ35mb6PNmU353avSotoodvFGgL7KjN562/OzHh+n1AoGAFBFnvge50H2FTT2MlKZ53yY27OAuKK2+KUQGK8OIP4fSWvisFzA68cQrejyAxkx4JMMic0OnHgLMi75Noz6aUYDdtRmuzkmxugz96bhFuj1UhH3HqqaLwn8yrw68X4dUD6eSv7sBhL9RJTVz3cuaR1wFaXZfEhfVcdRlvDYfa0k=";
        string pubkeyEncrypt = "MIIBCgKCAQEAxKrM4LqoQ7O37Wiybx/80NUwi9dDc+hP5MWx/uAyaoWsCTE3AXTcANqKR4MWd8FDKpyJn9WrIDaRnl4XuW8992Bpzqo4KbHlefQ6z848ox7M8BCqyiQ0uz5FeezFzhe1FBGpRmw1o1rH3mpjnkjpb81wWY6NyI6k7/ZUIQFX5Sn8g4vnaGNBlnhhd3oh8esM2IhoDcPvK2QXnpCa1o+md7O3VM1J1M2jIVvULaE5dxz2NIUCQnxFCgH/XYKfcEZEwjBubkFK2HP+pPKo0ZX9kfQ2MPOj7l04YTikA2Majym3BL38U/bNSt8rYHg5EIWwwObYxlo6NOWQRFYM9c1fZQIDAQAB";
        string prikeyEncrypt = "MIIEpAIBAAKCAQEAxKrM4LqoQ7O37Wiybx/80NUwi9dDc+hP5MWx/uAyaoWsCTE3AXTcANqKR4MWd8FDKpyJn9WrIDaRnl4XuW8992Bpzqo4KbHlefQ6z848ox7M8BCqyiQ0uz5FeezFzhe1FBGpRmw1o1rH3mpjnkjpb81wWY6NyI6k7/ZUIQFX5Sn8g4vnaGNBlnhhd3oh8esM2IhoDcPvK2QXnpCa1o+md7O3VM1J1M2jIVvULaE5dxz2NIUCQnxFCgH/XYKfcEZEwjBubkFK2HP+pPKo0ZX9kfQ2MPOj7l04YTikA2Majym3BL38U/bNSt8rYHg5EIWwwObYxlo6NOWQRFYM9c1fZQIDAQABAoIBACr8vn2cryzlOp3NFbuOfV9USiE280qBi/0QbWCttrdr8ner5z8NQQ16t2D8OUwB1WGaB8cFGDuZUekQ3hStSRkqXNZMhKwwc11d0gEcLkrlb5xFuF8o3NHUwbDt3Sq4Kd9yINMA0hSbwjZOgOnXPBcxC463xywAafL9n9P7DDBNw17l2ykW7gJtNRy6tf2kjCEfnHEIgXZZ19xp/BfApYAcLb/v9C/tRaWAzWLLTwX9GEOrJ2XjzIUOrdCmdO85VbH3b2bGHWwi2orbD+uvCZOPcCsOyQjUme40JaDQwgkCPTh/9F5/u/Z8sVcCw/mgzoaxWImdCwwQCj49FhT52V0CgYEA/CEL1VlL5Gb2tolhG8hufORzu2Id0uDNKsUZd92hM4Y98tyDnCqE/F3jiv63G0utHSzC3Rt77iiX9LXXV3AP/Zz91LNEm/vICSEeDOFejx7XEsnjsJuoDMZPt+bNu4bFWv0j81fuVyZ9ZPoy4xb+abmkebq9F2QxvcQs2DO+SKMCgYEAx6/FEaGKk10XWCdFEBeI3I3GViDYzSBEEnaI+wSR7VPBZkCt0w2aD4/wrw3pmlTAkN882GDdFzojtEd7t2nXgp03S0F5T5aGD4pFZWaqUYqz/bQ/UxBp0C5qHR084J5XarllTPBzbZ0fo1eY1Cde/mj/TD722o+9hUsmbi0NkFcCgYEAsZRY8FCvmlRG6jQCeH4IC+Ef/lfR56g7+SbPlFQ+aLrhQP+9lq1/8vvx+wECWLBJYqYXLYJhHFHtDQdSf5xHNvpu8XO+HBsPPhbcQngtkKJJG0ulGcvYZf77QOzH9I+syzRGMOu6zBko8okidD3KvQ5q4O38ptAEFMNqTnDLUf8CgYB6k/VfG1DboRuBa6nDdQ74hLcpi8RKNvJSex0fKfECRJXF1RJfKkxWHT/b1ah+qmQDCmZpVRyi83eTZQYW0wwOC8AznB+BsZ7dzz1GP71xjLlslccBkGPD/Zn6AUarg8eZpfD/R+MzeG5BcLZKFVkExyNghI44IGBwgG841sMqxQKBgQD6nSV5kw8RXBlzWfjI/q9hU0f9U4E2ZX66iNrUhlmK12yDXd0l3I4vpffo2HQVHRGP+4LKnX7g+7P6Zrs3GHoOg7EbnYjcReoBNoxwgTx93b6qBEi9yfQNYVPgZIwxMYq62yNlTcAp9CQLAwkOWaTO51viAVICUOmbQelIny9cMA==";
        RSA rsaSigning = RSA.Create();
        rsaSigning.ImportRSAPublicKey(Convert.FromBase64String(pubkeySigning), out int bytesread);
        RSA rsaEncrypt = RSA.Create();
        rsaEncrypt.ImportRSAPrivateKey(Convert.FromBase64String(prikeyEncrypt), out int bytesread1);
        Clims = new Dictionary<string, object>();
        ClaimsPrincipal principal = null;
        if (string.IsNullOrWhiteSpace(Token))
        {
            return false;
        }
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
        try
        {
            JwtSecurityToken jwt = handler.ReadJwtToken(Token);
            if (jwt == null)
            {
                return false;
            }
            TokenValidationParameters validationParameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                ClockSkew = TimeSpan.Zero,
                //IssuerSigningKey = new SymmetricSecurityKey(signingKey),
                //TokenDecryptionKey = new SymmetricSecurityKey(encKey),
                IssuerSigningKey = new RsaSecurityKey(rsaSigning.ExportParameters(false)),//公钥解密 --签名算法
                TokenDecryptionKey = new RsaSecurityKey(rsaEncrypt.ExportParameters(true)),//私钥解密--解密算法
                ValidateIssuer = true,//是否验证Issuer
                ValidateAudience = true,//是否验证Audience
                ValidateLifetime = _jwtConfig.ValidateLifetime,//是否验证失效时间
                ValidAudience = _jwtConfig.Audience,
                ValidIssuer = _jwtConfig.Issuer,
                ValidateIssuerSigningKey = true,//是否验证签名
            };
            principal = handler.ValidateToken(Token, validationParameters, out SecurityToken securityToken);
            foreach (Claim item in principal.Claims)
            {
                Clims.Add(item.Type, item.Value);
            }
            return true;
        }
        catch (SecurityTokenInvalidLifetimeException ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }
}

}
用非对称加密生成的jwt串更长,限制是被加密内容不能超出密钥长度

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值