【RSA】在 ASP.NET Core中结合web前端JsEncrypt.JS使用公钥加密,.NET Core使用私钥解密;

有一个需求,前端web使用的是JsEncrypt把后端给的公钥对密码进行加密,然后后端对其进行解密;

使用的类库如下:

  • 后端使用第三方开源类库Bouncy Castle进行RSA的加解密和生成PEM格式密钥对操作;
  • 前端web使用JsEncrypt.js进行RSA的加解密和生成密钥对操作。

首先,由后端生成公钥,将公钥传回前端,接口保存私钥;

复制代码
        /// <summary>
        /// 生成PEM格式的公钥和密钥
        /// </summary>
        /// <param name="strength">长度</param>
        /// <returns>Item2:公钥;Item1:私钥;</returns>
        public static (string, string) CreateKeyPair(int strength = 1024)
        {
            RsaKeyPairGenerator r = new RsaKeyPairGenerator();
            r.Init(new KeyGenerationParameters(new SecureRandom(), strength));
            AsymmetricCipherKeyPair keys = r.GenerateKeyPair();

            TextWriter privateTextWriter = new StringWriter();
            PemWriter privatePemWriter = new PemWriter(privateTextWriter);
            privatePemWriter.WriteObject(keys.Private);
            privatePemWriter.Writer.Flush();


            TextWriter publicTextWriter = new StringWriter();
            PemWriter publicPemWriter = new PemWriter(publicTextWriter);
            publicPemWriter.WriteObject(keys.Public);
            publicPemWriter.Writer.Flush();


            return (publicTextWriter.ToString(), privateTextWriter.ToString());
        }
复制代码

然后前端JsEncrypt拿到公钥后进行加密:

复制代码
      //rsa加密随机密钥
      var rsa = new JsEncrypt();

      //设置后端接口传回的公钥(无需对公钥字符串做任何处理)
      rsa.setPublicKey("<你的公钥>");

      //注意:RSA加解密有大小限制(最多117 bytes)
      var rsaEncrypted = rsa.encrypt("<待加密的字符串>");

      //已加密的字符串(Base64)
      console.log('rsaEncrypted:' + rsaEncrypted);
复制代码

后端接口拿到已加密的Base64进行解密:

复制代码
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="privateKey">私钥</param>
        /// <param name="decryptstring">待解密的字符串(Base64)</param>
        /// <returns>解密后的字符串</returns>
        public static string Decrypt(string privateKey, string decryptstring)
        {
            using (TextReader reader = new StringReader(privateKey))
            {
                dynamic key = new PemReader(reader).ReadObject();
                var rsaDecrypt = new Pkcs1Encoding(new RsaEngine());
                if (key is AsymmetricKeyParameter)
                {
                    key = (AsymmetricKeyParameter)key;
                }
                else if (key is AsymmetricCipherKeyPair)
                {
                    key = ((AsymmetricCipherKeyPair)key).Private;
                }
                rsaDecrypt.Init(false, key);  //这里加密是true;解密是false  

                byte[] entData = Convert.FromBase64String(decryptstring);
                entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length);
                return Encoding.UTF8.GetString(entData);
            }
        }
复制代码

在这里有一个坑,看关键代码:

var rsaDecrypt = new Pkcs1Encoding(new RsaEngine())

与前端JsEncrypt交互一定要按照上面的方法使用Pkcs1Encoding;如果按照下面这样写解密出来的字符串会乱码:

var rsaDecrypt = new RsaEngine();

最后附上加密方法:

复制代码
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="encryptstring">待加密的字符串</param>
        /// <returns>加密后的Base64</returns>
        public static string Encrypt(string publicKey, string encryptstring)
        {
            using (TextReader reader = new StringReader(publicKey))
            {
                AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter;
                Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine());
                pkcs1.Init(true, key);//加密是true;解密是false;
                byte[] entData = Encoding.UTF8.GetBytes(encryptstring);
                entData = pkcs1.ProcessBlock(entData, 0, entData.Length);
                return Convert.ToBase64String(entData);
            }
        }
复制代码

 

posted @   旋风小伙  阅读(2350)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示