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


    参考文档:

    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:Squareopensslin
    sa_public_key.pem");
                string privateKey = File.ReadAllText(@"D:Squareopensslin
    sa_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));
    
    
            }

    测试结果:

  • 相关阅读:
    Flask上下文管理及源码刨析
    Python数据库连接池DBUtils
    装饰器的修复wraps,偏函数partial 以及chain
    unity官方案例精讲(第三章)--星际航行游戏Space Shooter
    c#多态性
    C# 继承
    c#类(class)
    一、事件函数的执行顺序(脚本的生命周期)
    一、Vuforia_AR
    四、其它(一)
  • 原文地址:https://www.cnblogs.com/peterzhang123/p/12856669.html
Copyright © 2020-2023  润新知