123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- using Org.BouncyCastle.Asn1.Pkcs;
- using Org.BouncyCastle.Asn1.X509;
- using Org.BouncyCastle.Crypto;
- using Org.BouncyCastle.Crypto.Encodings;
- using Org.BouncyCastle.Crypto.Engines;
- using Org.BouncyCastle.Crypto.Parameters;
- using Org.BouncyCastle.Math;
- using Org.BouncyCastle.OpenSsl;
- using Org.BouncyCastle.Pkcs;
- using Org.BouncyCastle.Security;
- using Org.BouncyCastle.X509;
- using System;
- using System.IO;
- using System.Security.Cryptography;
- using System.Text;
- namespace ProjectManagementSystem.Common.Function
- {
- public class RSAHelper
- {
- //参考连接:https://www.jianshu.com/p/faefcc58c79b
- //工具网址1:https://the-x.cn/certificate/PemToXml.aspx
- //工具网址2:https://superdry.apphb.com/tools/online-rsa-key-converter
- //需要依赖一个第三方库,叫BouncyCastle ;在线获取安装包的代码是:PM >Install-Package BouncyCastle
- //安装步骤:VS中选择 工具(T)---》NuGet包管理器(N)---》程序包管理器控制台(O)---》然后数据以上代码即可
- #region Demo示例
- public static void Demo()
- {
- string xmlgy = "";
- string xmlsy = "";
- string xmlmdata = "";
- string xmljdata = "";
- string xmlsign = "";
- string xmlresult = "";
- string pemgy = "";
- string pemsy = "";
- string pemmdata = "";
- string pemjdata = "";
- string pemsign = "";
- string pemresult = "";
- RSAHelper.GetXMLRSAKeys(out xmlsy, out xmlgy);
- RSAHelper.GetPEMRSAKeys(out pemsy, out pemgy);
- string str1 = "1234567890";
- Console.WriteLine("===================xml===================");
- Console.WriteLine("===================xml公钥");
- Console.WriteLine(xmlgy);
- Console.WriteLine("===================xml私钥");
- Console.WriteLine(xmlsy);
- Console.WriteLine("===================xml公钥加密后的数据");
- xmlmdata = RSAHelper.XMLRSAEncrypt(xmlgy, str1);
- Console.WriteLine(xmlmdata);
- Console.WriteLine("===================xml私钥解密后的字符");
- xmljdata = RSAHelper.XMLRSADecrypt(xmlsy, xmlmdata);
- Console.WriteLine(xmljdata);
- Console.WriteLine("===================xml私钥加签后的sign");
- xmlsign = RSAHelper.XMLSign(xmlmdata, xmlsy);
- Console.WriteLine(xmlsign);
- Console.WriteLine("===================xml公钥验签后的结果");
- xmlresult = RSAHelper.XMLSignCheck(xmlmdata, xmlsign, xmlgy).ToString();
- Console.WriteLine(xmlresult);
- Console.WriteLine("===================xml===================");
- Console.WriteLine("=========================================*****=========================================");
- Console.WriteLine("===================pem===================");
- Console.WriteLine("===================pem公钥");
- Console.WriteLine(pemgy);
- Console.WriteLine("===================pem私钥");
- Console.WriteLine(pemsy);
- Console.WriteLine("===================pem公钥加密后的数据");
- pemmdata = RSAHelper.PEMRSAEncrypt(pemgy, str1);
- Console.WriteLine(pemmdata);
- Console.WriteLine("===================pem私钥解密后的字符");
- pemjdata = RSAHelper.PEMRSADecrypt(pemsy, pemmdata);
- Console.WriteLine(pemjdata);
- Console.WriteLine("===================pem私钥加签后的sign");
- pemsign = RSAHelper.PEMSign(pemmdata, pemsy);
- Console.WriteLine(pemsign);
- Console.WriteLine("===================pem公钥验签后的结果");
- pemresult = RSAHelper.PEMSignCheck(pemmdata, pemsign, pemgy).ToString();
- Console.WriteLine(pemresult);
- Console.WriteLine("===================pem===================");
- }
- #endregion
- #region 获取RSA密钥对
- /// <summary>
- /// 获取XML格式密钥对
- /// </summary>
- /// <param name="xmlprikey">xml私钥</param>
- /// <param name="xmlpubkey">xml公钥</param>
- public static void GetXMLRSAKeys(out string xmlprikey, out string xmlpubkey)
- {
- try
- {
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- xmlprikey = rsa.ToXmlString(true);
- xmlpubkey = rsa.ToXmlString(false);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 获取PEM格式密钥对
- /// </summary>
- /// <param name="pemprikey">pem私钥</param>
- /// <param name="pempubkey">pem公钥</param>
- public static void GetPEMRSAKeys(out string pemprikey, out string pempubkey)
- {
- try
- {
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- pemprikey = XMLToPEM_Pri(rsa.ToXmlString(true));
- pempubkey = XMLToPEM_Pub(rsa.ToXmlString(false));
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region RSA加密
- /// <summary>
- /// 使用XML格式加密
- /// </summary>
- /// <param name="xmlpubkey">xml公钥</param>
- /// <param name="encryptstr">需要加密的字符串</param>
- /// <returns>返回加密后的字符串</returns>
- public static string XMLRSAEncrypt(string xmlpubkey, string encryptstr)
- {
- byte[] PlainTextBArray;
- byte[] CypherTextBArray;
- string Result;
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlpubkey);
- PlainTextBArray = (new UTF8Encoding()).GetBytes(encryptstr);
- CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);
- Result = Convert.ToBase64String(CypherTextBArray);
- return Result;
- }
- /// <summary>
- /// 使用PEM格式加密
- /// </summary>
- /// <param name="pempubkey">pem公钥</param>
- /// <param name="encryptstr">需要加密的字符串</param>
- /// <returns>返回加密后的字符串</returns>
- public static string PEMRSAEncrypt(string pempubkey, string encryptstr)
- {
- StringReader sr = new StringReader(pempubkey);
- AsymmetricKeyParameter publickey = new PemReader(sr).ReadObject() as AsymmetricKeyParameter;
- if (publickey == null)
- throw new Exception("PEM格式公钥不能为空");
- try
- {
- var engine = new Pkcs1Encoding(new RsaEngine());
- engine.Init(true, publickey);
- byte[] bytes = Encoding.UTF8.GetBytes(encryptstr);//Encoding.UTF8.GetBytes(data);
- bytes = engine.ProcessBlock(bytes, 0, bytes.Length);
- return Convert.ToBase64String(bytes);// Convert.ToBase64String(bytes);
- }
- catch
- {
- throw new Exception("加密失败");
- }
- }
- #endregion
- #region RSA解密
- /// <summary>
- /// 使用XML格式解密
- /// </summary>
- /// <param name="xmlprikey">xml格式私钥</param>
- /// <param name="decryptstr">需要解密的字符串</param>
- /// <returns>返回解密后的字符串</returns>
- public static string XMLRSADecrypt(string xmlprikey, string decryptstr)
- {
- try
- {
- byte[] PlainTextBArray;
- byte[] DypherTextBArray;
- string Result;
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlprikey);
- PlainTextBArray = Convert.FromBase64String(decryptstr);
- DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
- Result = (new UTF8Encoding()).GetString(DypherTextBArray);
- return Result;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 使用PEM格式解密
- /// </summary>
- /// <param name="pemprikey">pem格式私钥</param>
- /// <param name="decryptstr">需要解密的字符串</param>
- /// <returns>返回解密后的字符串</returns>
- public static string PEMRSADecrypt(string pemprikey, string decryptstr)
- {
- byte[] bytes = Convert.FromBase64String(decryptstr);// Convert.FromBase64String(data);
- StringReader sr = new StringReader(pemprikey);
- AsymmetricKeyParameter prikey = new PemReader(sr).ReadObject() as AsymmetricKeyParameter;
- if (prikey == null)
- throw new Exception("私钥读取失败");
- try
- {
- var engine = new Pkcs1Encoding(new RsaEngine());
- engine.Init(false, prikey);
- bytes = engine.ProcessBlock(bytes, 0, bytes.Length);
- return Encoding.UTF8.GetString(bytes);////Encoding.UTF8.GetString(bytes);
- }
- catch
- {
- throw new Exception("解密失败");
- }
- }
- #endregion
- #region RSA签名
- /// <summary>
- /// 使用XML格式的私钥加签
- /// </summary>
- /// <param name="str">需要加签的字符串</param>
- /// <param name="xmlprikey">xml格式的私钥</param>
- /// <returns>返回签名</returns>
- public static string XMLSign(string str, string xmlprikey)
- {
- //根据需要加签时的哈希算法转化成对应的hash字符节
- byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
- var sha256 = new SHA256CryptoServiceProvider();
- byte[] rgbHash = sha256.ComputeHash(bt);
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
- key.FromXmlString(xmlprikey);
- RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
- formatter.SetHashAlgorithm("SHA256"); //此处是你需要加签的hash算法,需要和上边你计算的hash值的算法一致,不然会报错。
- byte[] inArray = formatter.CreateSignature(rgbHash);
- return Convert.ToBase64String(inArray);
- }
- /// <summary>
- /// 使用PEM格式的私钥加签
- /// </summary>
- /// <param name="str">需要加签的字符串</param>
- /// <param name="pemprikey">pem格式的私钥</param>
- /// <returns>返回签名</returns>
- public static string PEMSign(string str, string pemprikey)
- {
- pemprikey = PEMToXML_All(pemprikey, true);
- //根据需要加签时的哈希算法转化成对应的hash字符节
- byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
- var sha256 = new SHA256CryptoServiceProvider();
- byte[] rgbHash = sha256.ComputeHash(bt);
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
- key.FromXmlString(pemprikey);
- RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
- formatter.SetHashAlgorithm("SHA256"); //此处是你需要加签的hash算法,需要和上边你计算的hash值的算法一致,不然会报错。
- byte[] inArray = formatter.CreateSignature(rgbHash);
- return Convert.ToBase64String(inArray);
- }
- #endregion
- #region RSA验签
- /// <summary>
- /// 使用XML格式的公钥验签
- /// </summary>
- /// <param name="str">需要验签的字符串</param>
- /// <param name="sign">签名</param>
- /// <param name="xmlpubkey">xml格式的公钥</param>
- /// <returns>是/否</returns>
- public static bool XMLSignCheck(string str, string sign, string xmlpubkey)
- {
- try
- {
- byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
- var sha256 = new SHA256CryptoServiceProvider();
- byte[] rgbHash = sha256.ComputeHash(bt);
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
- key.FromXmlString(xmlpubkey);
- RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
- deformatter.SetHashAlgorithm("SHA256");
- byte[] rgbSignature = Convert.FromBase64String(sign);
- if (deformatter.VerifySignature(rgbHash, rgbSignature))
- {
- return true;
- }
- return false;
- }
- catch
- {
- return false;
- }
- }
- /// <summary>
- /// 使用XML格式的公钥验签
- /// </summary>
- /// <param name="str">需要验签的字符串</param>
- /// <param name="sign">签名</param>
- /// <param name="pempubkey">pem格式的公钥</param>
- /// <returns>是/否</returns>
- public static bool PEMSignCheck(string str, string sign, string pempubkey)
- {
- try
- {
- pempubkey = PEMToXML_All(pempubkey, false);
- byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
- var sha256 = new SHA256CryptoServiceProvider();
- byte[] rgbHash = sha256.ComputeHash(bt);
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
- key.FromXmlString(pempubkey);
- RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
- deformatter.SetHashAlgorithm("SHA256");
- byte[] rgbSignature = Convert.FromBase64String(sign);
- if (deformatter.VerifySignature(rgbHash, rgbSignature))
- {
- return true;
- }
- return false;
- }
- catch (Exception)
- {
- return false;
- }
- }
- #endregion
- #region XML转PEM
- /// <summary>
- /// XML格式的公钥转PEM格式的公钥
- /// </summary>
- /// <param name="xmlpubkey">xml格式的公钥</param>
- /// <returns>pem格式的公钥</returns>
- public static string XMLToPEM_Pub(string xmlpubkey)
- {
- var rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlpubkey);
- var p = rsa.ExportParameters(false);
- RsaKeyParameters key = new RsaKeyParameters(false, new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent));
- SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key);
- byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
- string publicKey = Convert.ToBase64String(serializedPublicBytes);
- return Format(publicKey, true);
- }
- /// <summary>
- /// XML格式的私钥转PEM格式的私钥
- /// </summary>
- /// <param name="xmlprikey">xml格式的私钥</param>
- /// <returns>pem格式的私钥</returns>
- public static string XMLToPEM_Pri(string xmlprikey)
- {
- var rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlprikey);
- var p = rsa.ExportParameters(true);
- var key = new RsaPrivateCrtKeyParameters(
- new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
- new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
- new BigInteger(1, p.InverseQ));
- PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key);
- byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
- string privateKey = Convert.ToBase64String(serializedPrivateBytes);
- return Format(privateKey, false);
- }
- /// <summary>
- /// 格式化公钥/私钥
- /// </summary>
- /// <param name="key">生成的公钥/私钥</param>
- /// <param name="type">true:公钥 false:私钥</param>
- /// <returns>PEM格式的公钥/私钥</returns>
- private static string Format(string key, bool type)
- {
- string result = string.Empty;
- int length = key.Length / 64;
- for (int i = 0; i < length; i++)
- {
- int start = i * 64;
- result = result + key.Substring(start, 64) + "\r\n";
- }
- result = result + key.Substring(length * 64);
- //if (type)
- //{
- // result = result.Insert(0, "-----BEGIN PUBLIC KEY-----\r\n");
- // result += "\r\n-----END PUBLIC KEY-----";
- //}
- //else
- //{
- // result = result.Insert(0, "-----BEGIN PRIVATE KEY-----\r\n");
- // result += "\r\n-----END PRIVATE KEY-----";
- //}
- return result;
- }
- #endregion
- #region PEM转XML
- /// <summary>
- /// PEM格式的密钥转XML格式
- /// </summary>
- /// <param name="pemkey">pem格式的密钥</param>
- /// <param name="isprikey">true:私钥;false:公钥</param>
- /// <returns>xml格式密钥</returns>
- public static string PEMToXML_All(string pemkey, bool isprikey)
- {
- if (isprikey)
- {
- pemkey = pemkey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "");
- }
- else
- {
- pemkey = pemkey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
- }
- string rsaKey = string.Empty;
- object pemObject = null;
- RSAParameters rsaPara = new RSAParameters();
- using (StringReader sReader = new StringReader(pemkey))
- {
- var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sReader);
- pemObject = pemReader.ReadObject();
- }
- //RSA私钥
- if (isprikey)
- {
- RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(pemkey));
- rsaPara = new RSAParameters
- {
- Modulus = key.Modulus.ToByteArrayUnsigned(),
- Exponent = key.PublicExponent.ToByteArrayUnsigned(),
- D = key.Exponent.ToByteArrayUnsigned(),
- P = key.P.ToByteArrayUnsigned(),
- Q = key.Q.ToByteArrayUnsigned(),
- DP = key.DP.ToByteArrayUnsigned(),
- DQ = key.DQ.ToByteArrayUnsigned(),
- InverseQ = key.QInv.ToByteArrayUnsigned(),
- };
- }
- //RSA公钥
- else
- {
- RsaKeyParameters key = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(pemkey));
- rsaPara.Modulus = key.Modulus.ToByteArrayUnsigned();
- rsaPara.Exponent = key.Exponent.ToByteArrayUnsigned();
- }
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.ImportParameters(rsaPara);
- using (StringWriter sw = new StringWriter())
- {
- sw.Write(rsa.ToXmlString(isprikey ? true : false));
- rsaKey = sw.ToString();
- }
- return rsaKey;
- }
- #endregion
- }
- }
|