翼度科技»论坛 编程开发 .net 查看内容

前端请求参数加密、.NET 后端解密

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
本文详细介绍了前端请求参数加密、.NET 后端解密,文章较长,请各位看官耐心看完。

目录

一、前端使用“CryptoJS”,前端AES加密,.NET后端AES解密

1.1、加密解密效果图


1.2、CryptoJS介绍

CryptoJS是一个JavaScript的加解密的工具包。它支持多种的算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。
1.3、准备工作:安装“CryptoJS”

1.3.1、使用npm进行安装

npm安装命令如下:
  1. npm install crypto-js --save-dev
复制代码
1.3.2、Visual Studio中安装

1.3.2.1、选择“客户端库”


1.3.2.2、安装下载“CryptoJS”

在“添加客户端库”界面:

  • 提供程序:选择“unpkg”;
  • 库:输入“crypto-js@”,进行版本的选择;
  • 可选择:1、包括所有库文件;2、选择特定文件;
确认无误之后,点击“安装”即可。

1.4、H5页面代码中引用“crypto-js”

1.5、前端页面代码

1.5.1、Html代码

H5代码使用了Layui开原框架
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta name="viewport" content="width=device-width" />
  5.     <title>sometext</title>
  6.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  7.    
  8.    
  9.    
  10.        
  11.     <link href="/lib/layui/dist/css/layui.css" rel="stylesheet" />
  12.     <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
  13.    
  14. </head>
  15. <body>
  16.    
  17.         
  18.             
  19.                 脱敏/加密前的内容:
  20.             
  21.             <input type="password"  id="sourctText" placeholder="脱敏/加密前的内容" aria-label="sourctText" aria-describedby="basic-addon1">
  22.         
  23.         <br />
  24.         
  25.             
  26.                 加密后的内容:
  27.             
  28.             <input type="text"  id="encryptText" placeholder="加密后的内容" readonly="readonly" aria-label="encryptText" aria-describedby="basic-addon1">
  29.         
  30.         <br />
  31.         
  32.             
  33.                 脱敏/加密后的内容:
  34.             
  35.             <input type="text"  id="resText" placeholder="脱敏/加密后的内容" readonly="readonly" aria-label="resText" aria-describedby="basic-addon1">
  36.         
  37.         
  38.             <button id="submit" type="button" >提交</button>
  39.         
  40.    
  41. </body>
  42. </html>
复制代码
1.5.2、javascript代码

说明:CBC模式前、后端需要确定偏移量的值,并且保持一致,这样才能确保后端解密成功。
  1. [/code][size=5]1.6、.NET 后端代码[/size]
  2. [size=4]1.6.1、定义公共的密匙字段[/size]
  3. [code]/// <summary>
  4. /// //AES加密所需16位密匙
  5. /// </summary>
  6. private static readonly String strAesKey = "lucasnetLUCASNET";
  7. /// <summary>
  8. /// AES加密所需16位密匙向量
  9. /// </summary>
  10. private static readonly String strAesIv = "lucasnetLUCASNET";
复制代码
1.6.2、封装AES解密方法
  1. /// <summary>
  2. ///  AES 解密
  3. /// </summary>
  4. /// <param name="str">密文(待解密)</param>
  5. /// <returns></returns>
  6. public string AesDecrypt(string str)
  7. {
  8.     if (string.IsNullOrEmpty(str)) return null;
  9.     Byte[] toEncryptArray = Convert.FromBase64String(str);
  10.     using (RijndaelManaged rm = new RijndaelManaged())
  11.     {
  12.         rm.Key = Encoding.UTF8.GetBytes(strAesKey);
  13.         rm.IV = Encoding.UTF8.GetBytes(strAesIv);
  14.         rm.Mode = CipherMode.CBC;
  15.         rm.Padding = PaddingMode.PKCS7;
  16.         rm.FeedbackSize = 128;
  17.         ICryptoTransform encryptor = rm.CreateDecryptor(rm.Key, rm.IV);
  18.         Byte[] resultArray = encryptor.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
  19.         return Encoding.UTF8.GetString(resultArray);
  20.     }
  21. }
复制代码
1.6.3、编写API接口
  1. /// <summary>
  2. /// 解密接口
  3. /// </summary>
  4. /// <param name="ciphertextpwd">密码密文(待解密)</param>
  5. /// <param name="publicKey">公钥</param>
  6. /// <param name="privateKey">私钥</param>
  7. /// <returns></returns>
  8. [HttpPost]
  9. public IActionResult word_Encrypt(string ciphertextpwd)
  10. {
  11.     string resPwd = "";
  12.     try
  13.     {
  14.         resPwd = AesDecrypt(ciphertextpwd);
  15.         return Json(new { code = 200, msg = resPwd });
  16.     }
  17.     catch (Exception ex)
  18.     {
  19.         return Json(new { code = 220, msg = "AES解密时出现错误!!!" });
  20.     }
  21. }
复制代码
二、前端使用“JSEncrypt”,进行非对称RSA加密,.NET后端解密

2.1、加密解密效果图


2.2、非对称加密

所谓的非对称,即加密和解密用的不是同一个秘钥。比如用公钥加密,就要用私钥解密。非对称加密的安全性是要好于对称加密的,但是性能就比较差了。
2.3、RSA

非对称加密算法中常用的就是 RSA 了。它是由在 MIT 工作的 3 个人于 1977 年提出,RSA 这个名字的由来便是取自他们 3 人的姓氏首字母。我们在访问 github 等远程 git 仓库时,如果是使用 SSH 协议,需要生成一对公私秘钥,就可以使用 RSA 算法。
2.4、准备工作:安装“jsencrypt”

2.4.1、使用npm进行安装

npm安装命令如下:
  1. npm install jsencrypt
复制代码
2.4.2、Visual Studio中安装

2.4.2.1、选择“客户端库”


2.4.2.2、安装下载“jsencrypt”

在“添加客户端库”界面:

  • 提供程序:选择“unpkg”;
  • 库:输入“jsencrypt@”,进行版本的选择;
  • 可选择:1、包括所有库文件;2、选择特定文件;
确认无误之后,点击“安装”即可。

2.5、安装组件“BouncyCastle”

在菜单栏找到 工具 —> NuGet 包管理器 —> 管理解决方案的NuGet程序包 —> 浏览 —> 搜索 “BouncyCastle” —> 安装。

2.5.1、新建帮助类

2.5.1.1、添加C# RAS生成.NET公钥与私钥以及.NET公钥与私钥转Java公钥私钥类“RASKeyConversion”

可根据自己需求删除生成Java的
  1. using Org.BouncyCastle.Asn1.Pkcs;
  2. using Org.BouncyCastle.Asn1.X509;
  3. using Org.BouncyCastle.Crypto;
  4. using Org.BouncyCastle.Crypto.Parameters;
  5. using Org.BouncyCastle.Math;
  6. using Org.BouncyCastle.OpenSsl;
  7. using Org.BouncyCastle.Pkcs;
  8. using Org.BouncyCastle.Security;
  9. using Org.BouncyCastle.X509;
  10. using System;
  11. using System.Security.Cryptography;
  12. using System.Xml;
  13. namespace WebApplication1
  14. {
  15.     /// <summary>
  16.     /// C# RAS生成.NET公钥与私钥以及.NET公钥与私钥转Java公钥私钥类
  17.     /// </summary>
  18.     public class RASKeyConversion
  19.     {
  20.         /// <summary>
  21.         /// 第一个:C# 私钥;第二个:C# 公钥;第三个:JAVA私钥;第四个:JAVA公钥
  22.         /// </summary>
  23.         private static string[] sKeys = new String[4];
  24.         /// <summary>
  25.         /// 生成公钥与私钥方法
  26.         /// </summary>
  27.         /// <returns>第一个:C# 私钥;第二个:C# 公钥;第三个:JAVA私钥;第四个:JAVA公钥</returns>
  28.         public static string[] createPulbicKey(int size = 1024)
  29.         {
  30.             try
  31.             {
  32.                 //密钥格式要生成pkcs#1格式的  而不是pkcs#8格式的
  33.                 using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size))
  34.                 {
  35.                     //C# 私钥
  36.                     sKeys[0] = rsa.ToXmlString(true);
  37.                     //C# 公钥
  38.                     sKeys[1] = rsa.ToXmlString(false);
  39.                     //JAVA私钥
  40.                     sKeys[2] = RSAPrivateKeyDotNet2Java(sKeys[0]);
  41.                     //JAVA公钥
  42.                     sKeys[3] = RSAPublicKeyDotNet2Java(sKeys[1]);
  43.                     return sKeys;
  44.                 }
  45.             }
  46.             catch (Exception)
  47.             {
  48.                 return null;
  49.             }
  50.         }
  51.         /// <summary>   
  52.         /// RSA私钥格式转换,.net->java   
  53.         /// </summary>   
  54.         /// <param name="privateKey">.net生成的私钥</param>   
  55.         /// <returns></returns>   
  56.         public static string RSAPrivateKeyDotNet2Java(string privateKey)
  57.         {
  58.             XmlDocument doc = new XmlDocument();
  59.             doc.LoadXml(privateKey);
  60.             BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
  61.             BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
  62.             BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
  63.             BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
  64.             BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
  65.             BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
  66.             BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
  67.             BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
  68.             RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
  69.             PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
  70.             byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
  71.             return Convert.ToBase64String(serializedPrivateBytes);
  72.         }
  73.         /// <summary>   
  74.         /// RSA公钥格式转换,.net->java   
  75.         /// </summary>   
  76.         /// <param name="publicKey">.net生成的公钥</param>   
  77.         /// <returns></returns>   
  78.         public static string RSAPublicKeyDotNet2Java(string publicKey)
  79.         {
  80.             XmlDocument doc = new XmlDocument();
  81.             doc.LoadXml(publicKey);
  82.             BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
  83.             BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
  84.             RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
  85.             SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
  86.             byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
  87.             return Convert.ToBase64String(serializedPublicBytes);
  88.         }
  89.     }
  90. }
复制代码
2.5.1.2、添加RSA秘钥转换帮助类“RsaKeyConvert”
  1. using Org.BouncyCastle.Crypto.Parameters;
  2. using Org.BouncyCastle.Crypto;
  3. using Org.BouncyCastle.Pkcs;
  4. using Org.BouncyCastle.Security;
  5. using System.Xml.Linq;
  6. using Org.BouncyCastle.OpenSsl;
  7. using Org.BouncyCastle.Math;
  8. namespace WebApplication1 //命名空间依据自己的项目进行修改
  9. {
  10.     /// <summary>
  11.     /// RSA秘钥转换帮助类
  12.     /// </summary>
  13.     public class RsaKeyConvert
  14.     {
  15.         #region 其他格式的RSA秘钥转XML格式秘钥
  16.         /// <summary>
  17.         /// pem格式的RSA公钥字符串转XML格式公钥 Public Key Convert pem->xml
  18.         /// </summary>
  19.         /// <param name="publicKey">公钥字符串</param>
  20.         /// <returns></returns>
  21.         /// <exception cref="Exception"></exception>
  22.         public static string PublicKeyPemToXml(string publicKey)
  23.         {
  24.             publicKey = PublicKeyFormat(publicKey);
  25.             RsaKeyParameters rsaKeyParameters = new PemReader(new StringReader(publicKey)).ReadObject() as RsaKeyParameters;
  26.             if (rsaKeyParameters == null)
  27.             {
  28.                 throw new Exception("Public key format is incorrect");
  29.             }
  30.             XElement xElement = new XElement((XName?)"RSAKeyValue");
  31.             XElement content = new XElement((XName?)"Modulus", Convert.ToBase64String(rsaKeyParameters.Modulus.ToByteArrayUnsigned()));
  32.             XElement content2 = new XElement((XName?)"Exponent", Convert.ToBase64String(rsaKeyParameters.Exponent.ToByteArrayUnsigned()));
  33.             xElement.Add(content);
  34.             xElement.Add(content2);
  35.             return xElement.ToString();
  36.         }
  37.         /// <summary>
  38.         /// Pkcs1格式私钥转成Xml Pkcs1->xml
  39.         /// </summary>
  40.         /// <param name="privateKey">Pkcs1格式私钥字符串</param>
  41.         /// <returns></returns>
  42.         /// <exception cref="Exception"></exception>
  43.         public static string PrivateKeyPkcs1ToXml(string privateKey)
  44.         {
  45.             privateKey = Pkcs1PrivateKeyFormat(privateKey);
  46.             RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(((new PemReader(new StringReader(privateKey)).ReadObject() as AsymmetricCipherKeyPair) ?? throw new Exception("Private key format is incorrect")).Private));
  47.             XElement xElement = new XElement((XName?)"RSAKeyValue");
  48.             XElement content = new XElement((XName?)"Modulus", Convert.ToBase64String(rsaPrivateCrtKeyParameters.Modulus.ToByteArrayUnsigned()));
  49.             XElement content2 = new XElement((XName?)"Exponent", Convert.ToBase64String(rsaPrivateCrtKeyParameters.PublicExponent.ToByteArrayUnsigned()));
  50.             XElement content3 = new XElement((XName?)"P", Convert.ToBase64String(rsaPrivateCrtKeyParameters.P.ToByteArrayUnsigned()));
  51.             XElement content4 = new XElement((XName?)"Q", Convert.ToBase64String(rsaPrivateCrtKeyParameters.Q.ToByteArrayUnsigned()));
  52.             XElement content5 = new XElement((XName?)"DP", Convert.ToBase64String(rsaPrivateCrtKeyParameters.DP.ToByteArrayUnsigned()));
  53.             XElement content6 = new XElement((XName?)"DQ", Convert.ToBase64String(rsaPrivateCrtKeyParameters.DQ.ToByteArrayUnsigned()));
  54.             XElement content7 = new XElement((XName?)"InverseQ", Convert.ToBase64String(rsaPrivateCrtKeyParameters.QInv.ToByteArrayUnsigned()));
  55.             XElement content8 = new XElement((XName?)"D", Convert.ToBase64String(rsaPrivateCrtKeyParameters.Exponent.ToByteArrayUnsigned()));
  56.             xElement.Add(content);
  57.             xElement.Add(content2);
  58.             xElement.Add(content3);
  59.             xElement.Add(content4);
  60.             xElement.Add(content5);
  61.             xElement.Add(content6);
  62.             xElement.Add(content7);
  63.             xElement.Add(content8);
  64.             return xElement.ToString();
  65.         }
  66.         /// <summary>
  67.         /// 格式化公钥字符串
  68.         /// </summary>
  69.         /// <param name="str">公钥字符串</param>
  70.         /// <returns></returns>
  71.         public static string PublicKeyFormat(string str)
  72.         {
  73.             if (str.StartsWith("-----BEGIN PUBLIC KEY-----"))
  74.             {
  75.                 return str;
  76.             }
  77.             List<string> list = new List<string>();
  78.             list.Add("-----BEGIN PUBLIC KEY-----");
  79.             int num;
  80.             for (int i = 0; i < str.Length; i += num)
  81.             {
  82.                 num = ((str.Length - i < 64) ? (str.Length - i) : 64);
  83.                 list.Add(str.Substring(i, num));
  84.             }
  85.             list.Add("-----END PUBLIC KEY-----");
  86.             return string.Join(Environment.NewLine, list);
  87.         }
  88.         /// <summary>
  89.         /// 格式化Pkcs1私钥
  90.         /// </summary>
  91.         /// <param name="str">私钥字符串</param>
  92.         /// <returns></returns>
  93.         public static string Pkcs1PrivateKeyFormat(string str)
  94.         {
  95.             if (str.StartsWith("-----BEGIN RSA PRIVATE KEY-----"))
  96.             {
  97.                 return str;
  98.             }
  99.             List<string> list = new List<string>();
  100.             list.Add("-----BEGIN RSA PRIVATE KEY-----");
  101.             int num;
  102.             for (int i = 0; i < str.Length; i += num)
  103.             {
  104.                 num = ((str.Length - i < 64) ? (str.Length - i) : 64);
  105.                 list.Add(str.Substring(i, num));
  106.             }
  107.             list.Add("-----END RSA PRIVATE KEY-----");
  108.             return string.Join(Environment.NewLine, list);
  109.         }
  110.         #endregion
  111.         #region Xml格式的RSA秘钥转格式
  112.         /// <summary>
  113.         /// RSA公钥格式转换:Xml格式的公钥转Pem格式的公钥 xml->pem
  114.         /// </summary>
  115.         /// <param name="publicKey">Xml公钥字符串</param>
  116.         /// <returns></returns>
  117.         public static string PublicKeyXmlToPem(string publicKey)
  118.         {
  119.             XElement xElement = XElement.Parse(publicKey);
  120.             XElement xElement2 = xElement.Element((XName?)"Modulus");
  121.             XElement xElement3 = xElement.Element((XName?)"Exponent");
  122.             RsaKeyParameters obj = new RsaKeyParameters(isPrivate: false, new BigInteger(1, Convert.FromBase64String(xElement2.Value)), new BigInteger(1, Convert.FromBase64String(xElement3.Value)));
  123.             StringWriter stringWriter = new StringWriter();
  124.             PemWriter pemWriter = new PemWriter(stringWriter);
  125.             pemWriter.WriteObject(obj);
  126.             pemWriter.Writer.Close();
  127.             return stringWriter.ToString();
  128.         }
  129.         /// <summary>
  130.         /// RSA私钥格式转换:Xml格式的私钥转Pkcs1格式的私钥 xml->Pkcs1
  131.         /// </summary>
  132.         /// <param name="privateKey">Xml私钥字符串</param>
  133.         /// <returns></returns>
  134.         public static string PrivateKeyXmlToPkcs1(string privateKey)
  135.         {
  136.             XElement xElement = XElement.Parse(privateKey);
  137.             XElement xElement2 = xElement.Element((XName?)"Modulus");
  138.             XElement xElement3 = xElement.Element((XName?)"Exponent");
  139.             XElement xElement4 = xElement.Element((XName?)"P");
  140.             XElement xElement5 = xElement.Element((XName?)"Q");
  141.             XElement xElement6 = xElement.Element((XName?)"DP");
  142.             XElement xElement7 = xElement.Element((XName?)"DQ");
  143.             XElement xElement8 = xElement.Element((XName?)"InverseQ");
  144.             XElement xElement9 = xElement.Element((XName?)"D");
  145.             RsaPrivateCrtKeyParameters obj = new RsaPrivateCrtKeyParameters(new BigInteger(1, Convert.FromBase64String(xElement2.Value)), new BigInteger(1, Convert.FromBase64String(xElement3.Value)), new BigInteger(1, Convert.FromBase64String(xElement9.Value)), new BigInteger(1, Convert.FromBase64String(xElement4.Value)), new BigInteger(1, Convert.FromBase64String(xElement5.Value)), new BigInteger(1, Convert.FromBase64String(xElement6.Value)), new BigInteger(1, Convert.FromBase64String(xElement7.Value)), new BigInteger(1, Convert.FromBase64String(xElement8.Value)));
  146.             StringWriter stringWriter = new StringWriter();
  147.             PemWriter pemWriter = new PemWriter(stringWriter);
  148.             pemWriter.WriteObject(obj);
  149.             pemWriter.Writer.Close();
  150.             return stringWriter.ToString();
  151.         }
  152.         #endregion
  153.     }
  154. }
复制代码
2.5.1.3、添加RSA加密帮助类“RSACrypto”
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Security.Cryptography;
  6. using System.Security.Cryptography.X509Certificates;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace WebApplication1 //命名空间依据自己的项目进行修改
  10. {
  11.     /// <summary>
  12.     /// RSA加密帮助类
  13.     /// </summary>
  14.     public class RSACrypto
  15.     {
  16.         /// <summary>
  17.         /// 默认的私钥
  18.         /// </summary>
  19.         private const string defaultprivateKey = @"MIICXAIBAAKBgQCC0hrRIjb3noDWNtbDpANbjt5Iwu2NFeDwU16Ec87ToqeoIm2KI+cOs81JP9aTDk/jkAlU97mN8wZkEMDr5utAZtMVht7GLX33Wx9XjqxUsDfsGkqNL8dXJklWDu9Zh80Ui2Ug+340d5dZtKtd+nv09QZqGjdnSp9PTfFDBY133QIDAQABAoGAJBNTOITaP6LCyKVKyEdnHaKNAz0DS+V9UwjKhyAgfcAxwm3sDdd6FQCEW0TIJA7Np7rFYrGwcR1UOoKxkNxB10ACl6JX4rE7xKS6NLZumdwxON/KgDb+2SQtWEXDgBySZ7Znv/FhEp1RmoBDjZ05E99kILWO3ToorUM0Eq2GHQkCQQCnUMXgZa4HS0tu
  20. INzysgB37d7ene9+CIARyJphs079qao2UWCgXqen43Ob6GJUgulz7We+4JOZFld0TfEi1E5rAkEAyClQAVzafLO3gXgqH7tbRbPPx788+4opxT9QBo2Trzl6/3FlcC1PIZeqbQ/Oc2wT7jmidFnpyTEnM2p7Yq3U1wJBAILTWaX4W3dAnJ5j+9+Y51zfFiEjhRwbMWi2XmB+gAlAHOOUBeXfnWBdLQx/TEOgiUIoI7LQjxhoq8E5II+HSjkCQDlKSdH6B7dFoTJ3eGcYsykiLEiZ3hSJGSeR1Y/qmei/ZQsUI9qVvV56EJeivI6g0puO94ah7Z5eaT/4LFS0OIUCQDgLn586pGgeidLhQsIe/AR3y9YOCAygTFLxzmeBXOKtM90q4516KWlTtK2u99442mNi7hNmjryBVwk62foWo8w=";
  21.         /// <summary>
  22.         /// 默认公钥
  23.         /// </summary>
  24.         private const string defaultpublicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCC0hrRIjb3noDWNtbDpANbjt5Iwu2NFeDwU16Ec87ToqeoIm2KI+cOs81JP9aTDk/jkAlU97mN8wZkEMDr5utAZtMVht7GLX33Wx9XjqxUsDfsGkqNL8dXJklWDu9Zh80Ui2Ug+340d5dZtKtd+nv09QZqGjdnSp9PTfFDBY133QIDAQAB";
  25.         private RSACryptoServiceProvider _privateKeyRsaProvider;
  26.         private RSACryptoServiceProvider _publicKeyRsaProvider;
  27.         /// <summary>
  28.         /// RSA加密帮助类构造函数
  29.         /// </summary>
  30.         /// <param name="privateKey">RSA解密密匙</param>
  31.         /// <param name="publicKey">RSA加密密匙</param>
  32.         public RSACrypto(string privateKey = "", string publicKey = "")
  33.         {
  34.             //判断私钥密匙是否为空,为空,使用默认的私钥;
  35.             if (string.IsNullOrEmpty(privateKey))
  36.             {
  37.                 privateKey = defaultprivateKey;
  38.             }
  39.             //判断公钥密匙是否为空,为空,使用默认的公钥;
  40.             if (string.IsNullOrEmpty(publicKey))
  41.             {
  42.                 publicKey = defaultpublicKey;
  43.             }
  44.             //不为空:使用定义的私钥密匙创建
  45.             if (!string.IsNullOrEmpty(privateKey))
  46.             {
  47.                 _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
  48.             }
  49.             //不为空:使用定义的公钥密匙创建
  50.             if (!string.IsNullOrEmpty(publicKey))
  51.             {
  52.                 _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
  53.             }
  54.         }
  55.         public string GetPublicRsaKeyStr(string publicKey)
  56.         {
  57.             string keyStr = "";
  58.             CreateRsaProviderFromPublicKey(publicKey);
  59.             return keyStr;
  60.         }
  61.         /// <summary>
  62.         /// RSA解密
  63.         /// </summary>
  64.         /// <param name="cipherText">解密的密文字符串</param>
  65.         /// <returns></returns>
  66.         /// <exception cref="Exception"></exception>
  67.         public string RSADecrypt(string cipherText)
  68.         {
  69.             if (_privateKeyRsaProvider == null)
  70.             {
  71.                 throw new Exception("提供的RSA私钥为空");
  72.             }
  73.             if (string.IsNullOrEmpty(cipherText))
  74.             {
  75.                 return "";
  76.             }
  77.             return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(System.Convert.FromBase64String(cipherText), false));
  78.         }
  79.         /// <summary>
  80.         /// RSA解密
  81.         /// </summary>
  82.         /// <param name="cipherText">需要解密的密文字符串</param>
  83.         /// <param name="publicKeyString">私钥</param>
  84.         /// <param name="keyType">密钥类型XML/PEM</param>
  85.         /// <returns></returns>
  86.         public static string RSADecrypt(string cipherText, string privateKeyString, string keyType, int size = 1024)
  87.         {
  88.             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
  89.             switch (keyType)
  90.             {
  91.                 case "XML":
  92.                     rsa.FromXmlString(privateKeyString);
  93.                     break;
  94.                 case "PEM":
  95.                     break;
  96.                 default:
  97.                     throw new Exception("不支持的密钥类型");
  98.             }
  99.             int MaxBlockSize = rsa.KeySize / 8;    //解密块最大长度限制
  100.             //正常解密
  101.             if (cipherText.Length <= MaxBlockSize)
  102.             {
  103.                 byte[] hashvalueDcy = rsa.Decrypt(System.Convert.FromBase64String(cipherText), false);//解密
  104.                 return Encoding.GetEncoding("UTF-8").GetString(hashvalueDcy);
  105.             }
  106.             //分段解密
  107.             else
  108.             {
  109.                 using (MemoryStream CrypStream = new MemoryStream(System.Convert.FromBase64String(cipherText)))
  110.                 {
  111.                     using (MemoryStream PlaiStream = new MemoryStream())
  112.                     {
  113.                         Byte[] Buffer = new Byte[MaxBlockSize];
  114.                         int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
  115.                         while (BlockSize > 0)
  116.                         {
  117.                             Byte[] ToDecrypt = new Byte[BlockSize];
  118.                             Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);
  119.                             Byte[] Plaintext = rsa.Decrypt(ToDecrypt, false);
  120.                             PlaiStream.Write(Plaintext, 0, Plaintext.Length);
  121.                             BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
  122.                         }
  123.                         string output = Encoding.GetEncoding("UTF-8").GetString(PlaiStream.ToArray());
  124.                         return output;
  125.                     }
  126.                 }
  127.             }
  128.         }
  129.         /// <summary>
  130.         /// RSA加密
  131.         /// </summary>
  132.         /// <param name="text">需要进行加密的明文字符串</param>
  133.         /// <returns></returns>
  134.         /// <exception cref="Exception"></exception>
  135.         public string RSAEncrypt(string text)
  136.         {
  137.             if (_publicKeyRsaProvider == null)
  138.             {
  139.                 throw new Exception("提供的RSA公钥为空");
  140.             }
  141.             return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false));
  142.         }
  143.         /// <summary>
  144.         /// RSA加密
  145.         /// </summary>
  146.         /// <param name="clearText">需要加密的明文字符串</param>
  147.         /// <param name="publicKeyString">公钥</param>
  148.         /// <param name="keyType">密钥类型XML/PEM</param>
  149.         /// <returns></returns>
  150.         public static string RSAEncrypt(string clearText, string publicKeyString, string keyType, int size = 1024)
  151.         {
  152.             byte[] data = Encoding.GetEncoding("UTF-8").GetBytes(clearText);
  153.             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
  154.             switch (keyType)
  155.             {
  156.                 case "XML":
  157.                     rsa.FromXmlString(publicKeyString);
  158.                     break;
  159.                 case "PEM":
  160.                     break;
  161.                 default:
  162.                     throw new Exception("不支持的密钥类型");
  163.             }
  164.             //加密块最大长度限制,如果加密数据的长度超过 秘钥长度/8-11,会引发长度不正确的异常,所以进行数据的分块加密
  165.             int MaxBlockSize = rsa.KeySize / 8 - 11;
  166.             //正常长度
  167.             if (data.Length <= MaxBlockSize)
  168.             {
  169.                 byte[] hashvalueEcy = rsa.Encrypt(data, false); //加密
  170.                 return System.Convert.ToBase64String(hashvalueEcy);
  171.             }
  172.             //长度超过正常值
  173.             else
  174.             {
  175.                 using (MemoryStream PlaiStream = new MemoryStream(data))
  176.                 using (MemoryStream CrypStream = new MemoryStream())
  177.                 {
  178.                     Byte[] Buffer = new Byte[MaxBlockSize];
  179.                     int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
  180.                     while (BlockSize > 0)
  181.                     {
  182.                         Byte[] ToEncrypt = new Byte[BlockSize];
  183.                         Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);
  184.                         Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false);
  185.                         CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
  186.                         BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
  187.                     }
  188.                     return System.Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
  189.                 }
  190.             }
  191.         }
  192.         /// <summary>
  193.         /// 通过提供的RSA私钥来创建RSA
  194.         /// </summary>
  195.         /// <param name="privateKey">私钥字符串</param>
  196.         /// <returns></returns>
  197.         /// <exception cref="Exception"></exception>
  198.         private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)
  199.         {
  200.             byte[] privateKeyBits = System.Convert.FromBase64String(privateKey);
  201.             RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
  202.             RSAParameters RSAparams = new RSAParameters();
  203.             using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
  204.             {
  205.                 byte bt = 0;
  206.                 ushort twobytes = 0;
  207.                 twobytes = binr.ReadUInt16();
  208.                 if (twobytes == 0x8130)
  209.                 {
  210.                     binr.ReadByte();
  211.                 }
  212.                 else if (twobytes == 0x8230)
  213.                 {
  214.                     binr.ReadInt16();
  215.                 }
  216.                 else
  217.                 {
  218.                     throw new Exception("Unexpected value read binr.ReadUInt16()");
  219.                 }
  220.                 twobytes = binr.ReadUInt16();
  221.                 if (twobytes != 0x0102)
  222.                 {
  223.                     throw new Exception("Unexpected version");
  224.                 }
  225.                 bt = binr.ReadByte();
  226.                 if (bt != 0x00)
  227.                 {
  228.                     throw new Exception("Unexpected value read binr.ReadByte()");
  229.                 }
  230.                 RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
  231.                 RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
  232.                 RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
  233.                 RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
  234.                 RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
  235.                 RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
  236.                 RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
  237.                 RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
  238.             }
  239.             RSA.ImportParameters(RSAparams);
  240.             return RSA;
  241.         }
  242.         /// <summary>
  243.         /// 获取整数大小
  244.         /// </summary>
  245.         /// <param name="binr"></param>
  246.         /// <returns></returns>
  247.         private int GetIntegerSize(BinaryReader binr)
  248.         {
  249.             byte bt = 0;
  250.             byte lowbyte = 0x00;
  251.             byte highbyte = 0x00;
  252.             int count = 0;
  253.             bt = binr.ReadByte();
  254.             if (bt != 0x02)
  255.                 return 0;
  256.             bt = binr.ReadByte();
  257.             if (bt == 0x81)
  258.                 count = binr.ReadByte();
  259.             else
  260.                 if (bt == 0x82)
  261.             {
  262.                 highbyte = binr.ReadByte();
  263.                 lowbyte = binr.ReadByte();
  264.                 byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
  265.                 count = BitConverter.ToInt32(modint, 0);
  266.             }
  267.             else
  268.             {
  269.                 count = bt;
  270.             }
  271.             while (binr.ReadByte() == 0x00)
  272.             {
  273.                 count -= 1;
  274.             }
  275.             binr.BaseStream.Seek(-1, SeekOrigin.Current);
  276.             return count;
  277.         }
  278.         /// <summary>
  279.         /// 通过提供的RSA公钥来创建RSA
  280.         /// </summary>
  281.         /// <param name="publicKeyString">公钥字符串</param>
  282.         /// <returns></returns>
  283.         private RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)
  284.         {
  285.             // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
  286.             byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
  287.             byte[] x509key;
  288.             byte[] seq = new byte[15];
  289.             int x509size;
  290.             x509key = Convert.FromBase64String(publicKeyString);
  291.             x509size = x509key.Length;
  292.             // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------
  293.             using (MemoryStream mem = new MemoryStream(x509key))
  294.             {
  295.                 using (BinaryReader binr = new BinaryReader(mem))  //wrap Memory Stream with BinaryReader for easy reading
  296.                 {
  297.                     byte bt = 0;
  298.                     ushort twobytes = 0;
  299.                     twobytes = binr.ReadUInt16();
  300.                     if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
  301.                         binr.ReadByte();    //advance 1 byte
  302.                     else if (twobytes == 0x8230)
  303.                         binr.ReadInt16();   //advance 2 bytes
  304.                     else
  305.                         return null;
  306.                     seq = binr.ReadBytes(15);       //read the Sequence OID
  307.                     if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct
  308.                         return null;
  309.                     twobytes = binr.ReadUInt16();
  310.                     if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
  311.                         binr.ReadByte();    //advance 1 byte
  312.                     else if (twobytes == 0x8203)
  313.                         binr.ReadInt16();   //advance 2 bytes
  314.                     else
  315.                         return null;
  316.                     bt = binr.ReadByte();
  317.                     if (bt != 0x00)     //expect null byte next
  318.                         return null;
  319.                     twobytes = binr.ReadUInt16();
  320.                     if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
  321.                         binr.ReadByte();    //advance 1 byte
  322.                     else if (twobytes == 0x8230)
  323.                         binr.ReadInt16();   //advance 2 bytes
  324.                     else
  325.                         return null;
  326.                     twobytes = binr.ReadUInt16();
  327.                     byte lowbyte = 0x00;
  328.                     byte highbyte = 0x00;
  329.                     if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
  330.                         lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus
  331.                     else if (twobytes == 0x8202)
  332.                     {
  333.                         highbyte = binr.ReadByte(); //advance 2 bytes
  334.                         lowbyte = binr.ReadByte();
  335.                     }
  336.                     else
  337.                         return null;
  338.                     byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order
  339.                     int modsize = BitConverter.ToInt32(modint, 0);
  340.                     int firstbyte = binr.PeekChar();
  341.                     if (firstbyte == 0x00)
  342.                     {   //if first byte (highest order) of modulus is zero, don't include it
  343.                         binr.ReadByte();    //skip this null byte
  344.                         modsize -= 1;   //reduce modulus buffer size by 1
  345.                     }
  346.                     byte[] modulus = binr.ReadBytes(modsize);   //读取模量字节
  347.                     if (binr.ReadByte() != 0x02)            //期望指数数据为Integer
  348.                         return null;
  349.                     int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)
  350.                     byte[] exponent = binr.ReadBytes(expbytes);
  351.                     // ------- create RSACryptoServiceProvider instance and initialize with public key -----
  352.                     RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
  353.                     RSAParameters RSAKeyInfo = new RSAParameters();
  354.                     RSAKeyInfo.Modulus = modulus;
  355.                     RSAKeyInfo.Exponent = exponent;
  356.                     RSA.ImportParameters(RSAKeyInfo);
  357.                     return RSA;
  358.                 }
  359.             }
  360.         }
  361.         /// <summary>
  362.         /// 比较字节数组
  363.         /// </summary>
  364.         /// <param name="a"></param>
  365.         /// <param name="b"></param>
  366.         /// <returns></returns>
  367.         private bool CompareBytearrays(byte[] a, byte[] b)
  368.         {
  369.             if (a.Length != b.Length)
  370.             {
  371.                 return false;
  372.             }
  373.             int i = 0;
  374.             foreach (byte c in a)
  375.             {
  376.                 if (c != b[i])
  377.                 {
  378.                     return false;
  379.                 }
  380.                 i++;
  381.             }
  382.             return true;
  383.         }
  384.     }
  385. }
复制代码
2.6、.NET 控制器后端代码

2.6.1、视图控制图代码
  1. public IActionResult worddata()
  2. {
  3.     var dataStr = RASKeyConversion.createPulbicKey();
  4.     publicKey = RsaKeyConvert1.PublicKeyXmlToPem(dataStr[1]);
  5.     privateKey = RsaKeyConvert1.PrivateKeyXmlToPkcs1(dataStr[0]);
  6.     ViewBag.publicKey = publicKey;
  7.     ViewBag.privateKey = privateKey;
  8.     return View();
  9. }
复制代码
2.6.2、POST请求接口代码
  1. /// <summary>
  2. /// 解密接口
  3. /// </summary>
  4. /// <param name="pwd"></param>
  5. /// <param name="privateKey">私钥</param>
  6. /// <returns></returns>
  7. [HttpPost]
  8. public IActionResult wordEncrypt(string pwd, string privateKey)
  9. {
  10.     string resPwd = "";
  11.     try
  12.     {
  13.         string privateStr= RsaKeyConvert1.PrivateKeyPkcs1ToXml(privateKey);
  14.         resPwd = RSACrypto.RSADecrypt(pwd,privateStr,"XML");
  15.         return Json(new { code = 200, msg = resPwd });
  16.     }
  17.     catch (Exception ex)
  18.     {
  19.         return Json(new { code = 220, msg = "RSA解密时出现错误!!!" });
  20.     }
  21. }
复制代码
2.7、前端视图页面代码

2.7.1、Html代码
  1. @{
  2.     Layout = null;
  3. }
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7.     <meta name="viewport" content="width=device-width" />
  8.     <title>sometext</title>
  9.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  10.    
  11.    
  12.    
  13.    
  14.     <link href="/lib/layui/dist/css/layui.css" rel="stylesheet" />
  15.     <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
  16.    
  17. </head>
  18. <body>
  19.    
  20.         
  21.             
  22.                 脱敏/加密前的内容:
  23.             
  24.             <input type="password"  id="sourctText" placeholder="脱敏/加密前的内容" aria-label="sourctText" aria-describedby="basic-addon1">
  25.         
  26.         <br />
  27.         
  28.             
  29.                 加密后的内容:
  30.             
  31.             <input type="text"  id="encryptText" placeholder="加密后的内容" readonly="readonly" aria-label="encryptText" aria-describedby="basic-addon1">
  32.         
  33.         <input type="hidden" value="@ViewBag.publicKey" id="publicKey" readonly="readonly" />
  34.         <input type="hidden" value="@ViewBag.privateKey" id="privateKey" readonly="readonly" />
  35.         <br />
  36.         
  37.             
  38.                 脱敏/加密后的内容:
  39.             
  40.             <input type="text"  id="resText" placeholder="脱敏/加密后的内容" readonly="readonly" aria-label="resText" aria-describedby="basic-addon1">
  41.         
  42.         
  43.             <button id="submit" type="button" >提交</button>
  44.         
  45.    
  46. </body>
  47. </html>
复制代码
2.7.2、javascript代码

[code][/code]
来源:https://www.cnblogs.com/lucasDC/archive/2023/09/17/17707813.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具