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

有一個需求,前端web使用的是JsEncrypt把後端給的公鑰對密碼進行加密,而後後端對其進行解密;前端

使用的類庫以下:git

  • 後端使用第三方開源類庫Bouncy Castle進行RSA的加解密和生成PEM格式密鑰對操做;
  • 前端web使用JsEncrypt.js進行RSA的加解密和生成密鑰對操做。

首先,由後端生成公鑰,將公鑰傳回前端,接口保存私鑰;github

        /// <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拿到公鑰後進行加密:web

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

在這裏有一個坑,看關鍵代碼:
dom

var rsaDecrypt = new Pkcs1Encoding(new RsaEngine())

與前端JsEncrypt交互必定要按照上面的方法使用Pkcs1Encoding;若是按照下面這樣寫解密出來的字符串會亂碼:加密

var rsaDecrypt = new RsaEngine();

最後附上加密方法:spa

        /// <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);
            }
        }
相關文章
相關標籤/搜索