using System; using System.Collections.Generic; using System.Text; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Crypto.Encodings; namespace RSAUtility { public class RSAUtil { private static Encoding Encoding_UTF8 = Encoding.UTF8; /// /// KEY 结构体 /// public struct RSAKEY { /// /// 公钥 /// public string PublicKey { get; set; } /// /// 私钥 /// public string PrivateKey { get; set; } } public RSAKEY GetKey() { //RSA密钥对的构造器 RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator(); //RSA密钥构造器的参数 RsaKeyGenerationParameters param = new RsaKeyGenerationParameters( Org.BouncyCastle.Math.BigInteger.ValueOf(3), new Org.BouncyCastle.Security.SecureRandom(), 1024, //密钥长度 25); //用参数初始化密钥构造器 keyGenerator.Init(param); //产生密钥对 AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair(); //获取公钥和密钥 AsymmetricKeyParameter publicKey = keyPair.Public; AsymmetricKeyParameter privateKey = keyPair.Private; SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey); Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object(); byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8"); Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object(); byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8"); RSAKEY item = new RSAKEY() { PublicKey = Convert.ToBase64String(publicInfoByte), PrivateKey = Convert.ToBase64String(privateInfoByte) }; return item; } private AsymmetricKeyParameter GetPublicKeyParameter(string keyBase64) { keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", ""); byte[] publicInfoByte = Convert.FromBase64String(keyBase64); Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入 AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte); return pubKey; } private AsymmetricKeyParameter GetPrivateKeyParameter(string keyBase64) { keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", ""); byte[] privateInfoByte = Convert.FromBase64String(keyBase64); // Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入 // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey); AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte); return priKey; } /// /// 私钥加密 /// /// 加密内容 /// 私钥(Base64后的) /// 返回Base64内容 public string EncryptByPrivateKey(string data, string privateKey) { //非对称加密算法,加解密用 IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //加密 try { RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)GetPrivateKeyParameter(privateKey); engine.Init(true, key); byte[] byteData = Encoding_UTF8.GetBytes(data); int maxBlock = key.Modulus.BitLength / 8 - 11; List resultData = new List(); //多次加密位置指示器 int offSet = 0; for (int i = 0; byteData.Length > offSet; i++) { byte[] tmpByte = new byte[] { }; if (byteData.Length - offSet > maxBlock) { tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock); } else { tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet); } offSet = maxBlock * (i + 1); //中间结果加入结果数组 resultData.AddRange(tmpByte); } string cipherText = Convert.ToBase64String( Encoding.UTF8.GetBytes( Convert.ToBase64String(resultData.ToArray()))); return cipherText; } catch (Exception ex) { throw ex; } } /// /// 私钥解密 /// /// 待解密的内容 /// 私钥(Base64编码后的) /// 返回明文 public string DecryptByPrivateKey(string data, string privateKey) { data = data.Replace("\r", "").Replace("\n", "").Replace(" ", ""); //非对称加密算法,加解密用 IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //解密 try { RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)GetPrivateKeyParameter(privateKey); engine.Init(false, key); int maxBlock = key.Modulus.BitLength/8; //用于解密的原始数据,经过两次Base64解码 byte[] byteData = Convert.FromBase64String( Encoding.UTF8.GetString( Convert.FromBase64String(data))); List resultData = new List(); //多次加密位置指示器 int offSet = 0; for (int i = 0;byteData.Length>offSet ;i++) { byte[] tmpByte= new byte[] { }; if (byteData.Length - offSet > maxBlock) { tmpByte= engine.ProcessBlock(byteData, offSet, maxBlock); } else { tmpByte=engine.ProcessBlock(byteData, offSet, byteData.Length - offSet); } offSet = maxBlock * (i+1); //中间结果加入结果数组 resultData.AddRange(tmpByte); } return Encoding_UTF8.GetString(resultData.ToArray()); } catch (Exception ex) { throw ex; } } /// /// 公钥加密 /// /// 加密内容 /// 公钥(Base64编码后的) /// 返回Base64内容 public string EncryptByPublicKey(string data, string publicKey) { //非对称加密算法,加解密用 IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //加密 try { RsaKeyParameters key = (RsaKeyParameters)GetPublicKeyParameter(publicKey); engine.Init(true, key); byte[] byteData = Encoding_UTF8.GetBytes(data); int maxBlock = key.Modulus.BitLength / 8 - 11; List resultData = new List(); //多次加密位置指示器 int offSet = 0; for (int i = 0; byteData.Length > offSet; i++) { byte[] tmpByte = new byte[] { }; if (byteData.Length - offSet > maxBlock) { tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock); } else { tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet); } offSet = maxBlock * (i + 1); //中间结果加入结果数组 resultData.AddRange(tmpByte); } string cipherText = Convert.ToBase64String( Encoding.UTF8.GetBytes( Convert.ToBase64String(resultData.ToArray()))); return cipherText; } catch (Exception ex) { throw ex; } } /// /// 公钥解密 /// /// 待解密的内容 /// 公钥(Base64编码后的) /// 返回明文 public string DecryptByPublicKey(string data, string publicKey) { data = data.Replace("\r", "").Replace("\n", "").Replace(" ", ""); //非对称加密算法,加解密用 IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //解密 try { RsaKeyParameters key = (RsaKeyParameters)GetPublicKeyParameter(publicKey); engine.Init(false, key); //用于解密的原始数据,经过两次Base64解码 byte[] byteData = Convert.FromBase64String( Encoding.UTF8.GetString( Convert.FromBase64String(data))); int maxBlock = key.Modulus.BitLength / 8; List resultData = new List(); //多次加密位置指示器 int offSet = 0; for (int i = 0; byteData.Length > offSet; i++) { byte[] tmpByte = new byte[] { }; if (byteData.Length - offSet > maxBlock) { tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock); } else { tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet); } offSet = maxBlock * (i + 1); //中间结果加入结果数组 resultData.AddRange(tmpByte); } return Encoding_UTF8.GetString(resultData.ToArray()); } catch (Exception ex) { throw ex; } } } }