JWT 使用加密算法RS256 非对称加密解密

孤人 提交于 2020-08-15 21:32:16

参考文档:

https://gist.github.com/ssippe/8fc11c4d7e766e66f06db0431dba3f0a
https://github.com/dvsekhvalnov/jose-jwt

https://mac-blog.org.ua/dotnet-core-firebase-jwt/

 

需要引用如下包: jose-jwt (version=2.5.0)、BouncyCastle 版本不限

加密和解密方式为:私钥加密、公钥解密  

生成私钥、公钥可以利用openssl工具、也可以通过在线上工具生成

私钥:

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMu4IDG1XU6a7bXo
4V1jSnbKk9Eum2WguAyq+maCRcP9JoHlE/HmhPOjl91aN5gDHw3pgB7QMMkPkuyY
0aG9UiIo7PbBgjXsNBErprKa8G7GKhDN4B3m8jxEi1NLtCk2H8AEf8H/deGFXCde
fjQx0NDEDcTbJ8STfbsqrLhOq2xzAgMBAAECgYEAg1kZMNOd8IOFxqb7P2o4ZbUh
b1rciL8CS/CleBiAgOgkvtWDcZFOoYQV83sqoxFIIYEuwS88dTZcZb32U5EsdYEx
JvJwAAYnzpch/YAz0llvXSHzZwNfGGvs4qt0d74bFpPfveli82wSKMlykeajP2Ro
RQpOniTYOWrJ01UHdUECQQDt1KTj/Xs5BNmEZAkJVmGekQROADk+ztceAe9UMj/J
s5xECdXVwuFh2Rm62MMQNNoW2Pjz4Y5NqhjRu0MMZnlTAkEA20hZsgA78aqTO7s+
+y/CLgP3Cd7uG/5RkcmjBWq2eXkt6wmazZl0BMYb7vshblnMjFXJwuOmfBJl7rTr
1fg8YQJAEo4Jg0QObgdj1QFc9x6HJTDZLiC0VqMag1vRSTdWZK0fnutJhJDctp6S
dFJe/Y+yCCBLY/OP/50qrIo4k+oWwwJAIn8hTTVoOL6C5xSv9cgvnhmVlYHyp4i8
wFieQs3k4vtDVARwzANmExIvdssfGUMbQMCGOxihKkeirYjcyQ6CQQJAbsbpzCjD
wd9JCogmTu/xYqtL898ek7LeNkhgIY2KhYtlptxlHfzgLBUgiSTNTcD1YWtSSp6u
A5ImxrryDYPmfg==
-----END PRIVATE KEY-----

公钥:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLuCAxtV1Omu216OFdY0p2ypPR
LptloLgMqvpmgkXD/SaB5RPx5oTzo5fdWjeYAx8N6YAe0DDJD5LsmNGhvVIiKOz2
wYI17DQRK6aymvBuxioQzeAd5vI8RItTS7QpNh/ABH/B/3XhhVwnXn40MdDQxA3E
2yfEk327Kqy4TqtscwIDAQAB
-----END PUBLIC KEY-----

核心代码:

/// <summary>
        /// JWT-RS256 加密
        /// 私钥加密,公钥解密
        /// </summary>
        /// <param name="payload">负荷部分,存储使用的信息</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        public static string JwtEncryptRS256(IDictionary<string, object> payload, string privateKey)
        {
            //可以扩展header
            //var headers = new Dictionary<string, object>()
            //{
            //     { "typ", "JWT" },
            //     { "cty", "JWT" },
            //     { "keyid", "111-222-333"}
            //};

            using (var rsa = GetRSACryptoServiceProvider(privateKey, true)) //读取私钥
            {
                var token = Jose.JWT.Encode(payload, rsa, Jose.JwsAlgorithm.RS256);
                //var token = Jose.JWT.Encode(payload, rsa, Jose.JwsAlgorithm.RS256, headers);  //带header
                return token;
            }
        }

        /// <summary>
        /// JWT-RS256 解密
        /// </summary>
        /// <param name="token">要解密的token</param>
        /// <param name="publicKey">公钥</param>
        /// <returns></returns>
        public static Dictionary<string, object> JwtDecryptRS256(string token, string publicKey)
        {
            try
            {
                using (var rsa = GetRSACryptoServiceProvider(publicKey, false)) //读取公钥
                {
                    var payload = Jose.JWT.Decode<Dictionary<string, object>>(token, rsa);
                    return payload;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// 根据 私钥 or 公钥 返回参数
        /// </summary>
        /// <param name="key">私钥 or 公钥</param>
        /// <returns></returns>
        private static RSACryptoServiceProvider GetRSACryptoServiceProvider(string key, bool isprivate)
        {
            try
            {
                RSAParameters rsaParams;
                if (isprivate)
                {
                    using (var sr = new StringReader(key))
                    {
                        // use BouncyCastle to convert the key to RSA parameters
                        //需要引用包 BouncyCastle
                        var pemReader = new PemReader(sr);
                        var keyPair = pemReader.ReadObject() as RsaPrivateCrtKeyParameters;
                        if (keyPair == null)
                        {
                            //没有读到Privatekey
                        }
                        rsaParams = DotNetUtilities.ToRSAParameters(keyPair);
                    }
                }
                else
                {
                    using (var sr = new StringReader(key))
                    {
                        var pemReader = new PemReader(sr);
                        var keyPair = pemReader.ReadObject() as RsaKeyParameters;
                        if (keyPair == null)
                        {
                            //没有读到Publickey
                        }
                        rsaParams = DotNetUtilities.ToRSAParameters(keyPair);
                    }
                }
                var rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(rsaParams);
                return rsa;
            }
            catch (Exception ex)
            {
                throw;
            }

        }

测试:

static void Main(string[] args)
        {

            string publicKey = File.ReadAllText(@"D:\Square\openssl\bin\rsa_public_key.pem");
            string privateKey = File.ReadAllText(@"D:\Square\openssl\bin\rsa_private_key.pem");

            int timestamp = TimeHelper.GetTimeStamp(DateTime.UtcNow.AddSeconds(5));  //时间戳 
            var payload = new Dictionary<string, object>
            {
                {"iss","123456"},
                {"exp",timestamp}   //5s
            };
            var gettoken = JosejwtHelper.JwtEncryptRS256(payload, privateKey);   //私钥加密
            Console.WriteLine("加密结果:" + gettoken);
            Console.WriteLine("....");

            var getvalue = JosejwtHelper.JwtDecryptRS256(gettoken, publicKey);   //公钥解密
            Console.WriteLine("解密结果:" + JsonConvert.SerializeObject(getvalue));


        }

测试结果:

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!