Rsa加密解密-可逆非对称加密
using System; using System.IO; using System.Security.Cryptography; namespace Common.Helper.Crypto { /// <summary> /// Rsa加密解密-可逆非对称加密(公钥加密算法) /// RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。 /// 安全性好,性能不如Des /// </summary> public static class RsaCrypto { #region 加密解密方式一:加密密钥和解密密钥相同 //参考:https://www.cnblogs.com/guohu/p/5562759.html /// <summary> /// 秘钥:加密、解密(秘钥相同,注意保存) /// </summary> /// <returns></returns> private static CspParameters GetCspKey() { CspParameters param = new CspParameters { KeyContainerName = "chait"//密匙容器的名称,保持加密解密一致才能解密成功 }; return param; } /// <summary> /// 加密 /// </summary> /// <param name="palinData">明文</param> /// <param name="encodingType">编码方式</param> /// <returns>密文</returns> public static string Encrypt(string palinData, EncodingStrOrByte.EncodingType encodingType = EncodingStrOrByte.EncodingType.UTF8) { if (string.IsNullOrWhiteSpace(palinData)) return null; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(GetCspKey())) { byte[] bytes = EncodingStrOrByte.GetBytes(palinData, encodingType); //将要加密的字符串转换为指定编码的字节数组 byte[] encryptData = rsa.Encrypt(bytes, false);//将加密后的字节数据转换为新的加密字节数组 return Convert.ToBase64String(encryptData);//将加密后的字节数组转换为字符串 } } /// <summary> /// 解密 /// </summary> /// <param name="encryptData">密文</param> /// <param name="encodingType">编码方式</param> /// <returns>明文</returns> public static string Decrypt(string encryptData, EncodingStrOrByte.EncodingType encodingType = EncodingStrOrByte.EncodingType.UTF8) { if (string.IsNullOrWhiteSpace(encryptData)) return null; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(GetCspKey())) { byte[] bytes = Convert.FromBase64String(encryptData); byte[] palinData = rsa.Decrypt(bytes, false); return EncodingStrOrByte.GetString(palinData, encodingType); } } #endregion #region 加密解密方式二:公钥加密/私钥解密 //参考:https://www.cnblogs.com/dudu/p/dotnet-core-rsa-openssl.html #region 公/私密钥 //openssl genrsa -out rsa_1024_priv.pem 1024 private static readonly string _privateKey = @"MIICXgIBAAKBgQC0xP5HcfThSQr43bAMoopbzcCyZWE0xfUeTA4Nx4PrXEfDvybJ EIjbU/rgANAty1yp7g20J7+wVMPCusxftl/d0rPQiCLjeZ3HtlRKld+9htAZtHFZ osV29h/hNE9JkxzGXstaSeXIUIWquMZQ8XyscIHhqoOmjXaCv58CSRAlAQIDAQAB AoGBAJtDgCwZYv2FYVk0ABw6F6CWbuZLUVykks69AG0xasti7Xjh3AximUnZLefs iuJqg2KpRzfv1CM+Cw5cp2GmIVvRqq0GlRZGxJ38AqH9oyUa2m3TojxWapY47zye PYEjWwRTGlxUBkdujdcYj6/dojNkm4azsDXl9W5YaXiPfbgJAkEA4rlhSPXlohDk FoyfX0v2OIdaTOcVpinv1jjbSzZ8KZACggjiNUVrSFV3Y4oWom93K5JLXf2mV0Sy 80mPR5jOdwJBAMwciAk8xyQKpMUGNhFX2jKboAYY1SJCfuUnyXHAPWeHp5xCL2UH tjryJp/Vx8TgsFTGyWSyIE9R8hSup+32rkcCQBe+EAkC7yQ0np4Z5cql+sfarMMm 4+Z9t8b4N0a+EuyLTyfs5Dtt5JkzkggTeuFRyOoALPJP0K6M3CyMBHwb7WsCQQCi TM2fCsUO06fRQu8bO1A1janhLz3K0DU24jw8RzCMckHE7pvhKhCtLn+n+MWwtzl/ L9JUT4+BgxeLepXtkolhAkEA2V7er7fnEuL0+kKIjmOm5F3kvMIDh9YC1JwLGSvu 1fnzxK34QwSdxgQRF1dfIKJw73lClQpHZfQxL/2XRG8IoA==".Replace("\n", ""); //openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem private static readonly string _publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0xP5HcfThSQr43bAMoopbzcCy ZWE0xfUeTA4Nx4PrXEfDvybJEIjbU/rgANAty1yp7g20J7+wVMPCusxftl/d0rPQ iCLjeZ3HtlRKld+9htAZtHFZosV29h/hNE9JkxzGXstaSeXIUIWquMZQ8XyscIHh qoOmjXaCv58CSRAlAQIDAQAB".Replace("\n", ""); #endregion /// <summary> /// 公钥加密 /// </summary> /// <param name="palinData">明文</param> /// <param name="encodingType">编码方式</param> /// <returns>string:密文</returns> public static string EncryptByPublicKey(string palinData, EncodingStrOrByte.EncodingType encodingType = EncodingStrOrByte.EncodingType.UTF8) { if (string.IsNullOrWhiteSpace(palinData)) return null; RSA rsa = CreateRsaFromPublicKey(_publicKey); byte[] palinDataBytes = EncodingStrOrByte.GetBytes(palinData, encodingType); byte[] encryptDataBytes = rsa.Encrypt(palinDataBytes, RSAEncryptionPadding.Pkcs1); return Convert.ToBase64String(encryptDataBytes); } /// <summary> /// 私钥解密 /// </summary> /// <param name="encryptData">密文</param> /// <param name="encodingType">编码方式</param> /// <returns>string:明文</returns> public static string DecryptByPrivateKey(string encryptData, EncodingStrOrByte.EncodingType encodingType = EncodingStrOrByte.EncodingType.UTF8) { if (string.IsNullOrWhiteSpace(encryptData)) return null; RSA rsa = CreateRsaFromPrivateKey(_privateKey); byte[] encryptDataBytes = Convert.FromBase64String(encryptData); byte[] palinDataBytes = rsa.Decrypt(encryptDataBytes, RSAEncryptionPadding.Pkcs1); return EncodingStrOrByte.GetString(palinDataBytes, encodingType); } /// <summary> /// 创建私钥 /// </summary> /// <param name="privateKey"></param> /// <returns></returns> private static RSA CreateRsaFromPrivateKey(string privateKey) { var privateKeyBits = Convert.FromBase64String(privateKey); var rsa = RSA.Create(); var RSAparams = new RSAParameters(); using (var binr = new BinaryReader(new MemoryStream(privateKeyBits))) { byte bt = 0; ushort twobytes = 0; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else throw new Exception("Unexpected value read binr.ReadUInt16()"); twobytes = binr.ReadUInt16(); if (twobytes != 0x0102) throw new Exception("Unexpected version"); bt = binr.ReadByte(); if (bt != 0x00) throw new Exception("Unexpected value read binr.ReadByte()"); RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.D = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.P = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr)); } rsa.ImportParameters(RSAparams); return rsa; } private static int GetIntegerSize(BinaryReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) { return count; } bt = binr.ReadByte(); if (bt == 0x81) { count = binr.ReadByte();} else if (bt == 0x82) { highbyte = binr.ReadByte(); lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else{ count = bt; } while (binr.ReadByte() == 0x00) { count -= 1; } binr.BaseStream.Seek(-1, SeekOrigin.Current); return count; } /// <summary> /// 创建公钥 /// </summary> /// <param name="publicKeyString"></param> /// <returns></returns> private static RSA CreateRsaFromPublicKey(string publicKeyString) { byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 }; byte[] x509key; byte[] seq = new byte[15]; int x509size; x509key = Convert.FromBase64String(publicKeyString); x509size = x509key.Length; using (var mem = new MemoryStream(x509key)) { using (var binr = new BinaryReader(mem)) { byte bt = 0; ushort twobytes = 0; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else return null; seq = binr.ReadBytes(15); if (!CompareBytearrays(seq, SeqOID)) return null; twobytes = binr.ReadUInt16(); if (twobytes == 0x8103) binr.ReadByte(); else if (twobytes == 0x8203) binr.ReadInt16(); else return null; bt = binr.ReadByte(); if (bt != 0x00) return null; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else return null; twobytes = binr.ReadUInt16(); byte lowbyte = 0x00; byte highbyte = 0x00; if (twobytes == 0x8102) lowbyte = binr.ReadByte(); else if (twobytes == 0x8202) { highbyte = binr.ReadByte(); lowbyte = binr.ReadByte(); } else return null; byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; int modsize = BitConverter.ToInt32(modint, 0); int firstbyte = binr.PeekChar(); if (firstbyte == 0x00) { binr.ReadByte(); modsize -= 1; } byte[] modulus = binr.ReadBytes(modsize); if (binr.ReadByte() != 0x02) return null; int expbytes = (int)binr.ReadByte(); byte[] exponent = binr.ReadBytes(expbytes); var rsa = RSA.Create(); var rsaKeyInfo = new RSAParameters { Modulus = modulus, Exponent = exponent }; rsa.ImportParameters(rsaKeyInfo); return rsa; } } } private static bool CompareBytearrays(byte[] a, byte[] b) { if (a.Length != b.Length) return false; int i = 0; foreach (byte c in a) { if (c != b[i]) return false; i++; } return true; } #endregion } }
编码处理类:
using System.Text; namespace Common.Helper { /// <summary> /// 处理编码字符串或字符串 /// </summary> public static class EncodingStrOrByte { /// <summary> /// 编码方式 /// </summary> public enum EncodingType { UTF7, UTF8, UTF32, Unicode, BigEndianUnicode, ASCII, GB2312 }; /// <summary> /// 处理指定编码的字符串,转换字节数组 /// </summary> /// <param name="str"></param> /// <param name="encodingType"></param> /// <returns></returns> public static byte[] GetByte(string str, EncodingType encodingType) { byte[] bytes = null; switch (encodingType) { //将要加密的字符串转换为指定编码的字节数组 case EncodingType.UTF7: bytes = Encoding.UTF7.GetBytes(str); break; case EncodingType.UTF8: bytes = Encoding.UTF8.GetBytes(str); break; case EncodingType.UTF32: bytes = Encoding.UTF32.GetBytes(str); break; case EncodingType.Unicode: bytes = Encoding.Unicode.GetBytes(str); break; case EncodingType.BigEndianUnicode: bytes = Encoding.BigEndianUnicode.GetBytes(str); break; case EncodingType.ASCII: bytes = Encoding.ASCII.GetBytes(str); break; case EncodingType.GB2312: bytes = Encoding.Default.GetBytes(str); break; } return bytes; } /// <summary> /// 处理指定编码的字节数组,转换字符串 /// </summary> /// <param name="myByte"></param> /// <param name="encodingType"></param> /// <returns></returns> public static string GetString(byte[] myByte, EncodingType encodingType) { string str = null; switch (encodingType) { //将要加密的字符串转换为指定编码的字节数组 case EncodingType.UTF7: str = Encoding.UTF7.GetString(myByte); break; case EncodingType.UTF8: str = Encoding.UTF8.GetString(myByte); break; case EncodingType.UTF32: str = Encoding.UTF32.GetString(myByte); break; case EncodingType.Unicode: str = Encoding.Unicode.GetString(myByte); break; case EncodingType.BigEndianUnicode: str = Encoding.BigEndianUnicode.GetString(myByte); break; case EncodingType.ASCII: str = Encoding.ASCII.GetString(myByte); break; case EncodingType.GB2312: str = Encoding.Default.GetString(myByte); break; } return str; } } }