• 【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);
                }
            }
  • 相关阅读:
    iOS controller 和 window 图层
    iOS CGAffineTransform 仿射变换
    iOS UIButton的UIEdgeInsets
    iOS UI的动态布局
    iOS 栅格动态布局
    iOS 系统键盘几个类型
    iOS 金融类高精度处理
    Sublime Text (崇高文本)
    iOS 静态库——制作bundle
    iOS 静态库——制作Framework
  • 原文地址:https://www.cnblogs.com/myhalo/p/9334282.html
走看看 - 开发者的网上家园