欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-11-20 23:34:57
参考文档: https://gist.github.com/ssippe/8fc11c4d7e766e66f06db0431dba3f0ahttps://github.com/dvsekhvalnov/jose-jwt https://mac-blog.org.ua/dotnet-core-fire ......

参考文档:

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));


        }

测试结果:

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