• C#常用的加密算法:MD5、Base64、SHA1、SHA256、HmacSHA256、DES、AES、RSA


    RSA生成C#的XML格式的公钥和私钥以及Java的Base64位公、私钥参考文章:C# RAS生成.NET公钥与私钥以及.NET公钥与私钥转Java公钥私钥类

    简介

    本文主要讲解一下C#常用的那些加密算法,包括MD5、Base64、SHA1、SHA256、HmacSHA256、DES、AES、RSA加密等,有需要的朋友可以参考下

    需要引用的类

    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.Security;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;

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

    我自己定义的公共字段;有需要的朋友可以自行定义

            private static CspParameters Param;
    
            /// <summary>
            /// SK(Secret Access Key):与访问密钥ID结合使用的密钥,对请求进行加密签名,可标识发送方,并防止请求被修改
            /// </summary>
            public static string _appSecret = ConfigurationManager.AppSettings["appSecret"].ToString();
    
            /// <summary>
            /// AK(Access Key ID):访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名
            /// </summary>
            public static string _appKey = ConfigurationManager.AppSettings["appKey"].ToString();
    
            /// <summary>
            /// DES密钥
            /// </summary>
            private static byte[] _KEY = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    
            /// <summary>
            /// DES向量
            /// </summary>
            private static byte[] _IV = new byte[] { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
    
            /// <summary>
            /// RSA加密/解密的默认公钥
            /// </summary>
            private static string _publicKey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
    
            /// <summary>
            /// RSA解密/加密的默认私钥
            /// </summary>
            private static string _privateKey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";
    
            /// <summary>
            /// 8位加密密钥
            /// </summary>
            private static string keys = "olikjhgb";
    
            /// <summary>
            /// 16位的加密秘钥
            /// </summary>
            private static string Key = "1123uyrlouhd@_Lq";
    
            /// <summary>
            /// 16位以上的默认向量
            /// </summary>
            private static string vector = "*abcdefghijklmnopqrst@";
    

    一、MD5加密

    • MD5加密是最常见的加密方式,因为MD5是不可逆的,所以很多系统的密码都是用MD5加密保存的。
    • 虽说MD5加密不可逆,但是我们可以对明文再次加密,进行两次加密的密文进行对比
            #region MD5加密解密
            /// <summary>
            /// 16位MD5加密
            /// </summary>
            /// <param name="laws">需要加密的明文字符串</param>
            /// <returns></returns>
            public static string MD5Encrypt16(string laws)
            {
                var md5 = new MD5CryptoServiceProvider();
                string cipherText = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(laws)), 4, 8);
                cipherText = cipherText.Replace("-", "");
                return cipherText;
            }
    
            /// <summary>
            /// 32位MD5加密
            /// </summary>
            /// <param name="laws">需要加密的明文字符串</param>
            /// <returns>32位MD5加密密文字符串</returns>
            public static string MD5Encrypt32(string laws)
            {
                string plainText = laws;
                string rule = "";
                MD5 md5 = MD5.Create(); //实例化一个md5对像
                                        // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
                byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(plainText));
                // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
                for (int i = 0; i < s.Length; i++)
                {
                    // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
                    rule = rule + s[i].ToString("x2");
                }
                return rule;
            }
    
            /// <summary>
            /// 64位MD5加密
            /// </summary>
            /// <param name="laws">需要加密的明文字符串</param>
            /// <returns>64位MD5加密密文字符串</returns>
            public static string MD5Encrypt64(string laws)
            {
                string rule = laws;
                MD5 md5 = MD5.Create(); //实例化一个md5对像
                // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
                byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(rule));
                return Convert.ToBase64String(s);
            }
    
            /// <summary>
            /// 对字符串进MD5加密
            /// </summary>
            /// <param name="sourceStr">源类型</param>
            /// <returns>加密后字符串</returns>
            public static string Md5Encrypt(string sourceStr)
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                //将要加密的字符串转换成字节数组
                byte[] palindata = Encoding.Default.GetBytes(sourceStr);
                //通过字节数组进行加密
                byte[] encryptdata = md5.ComputeHash(palindata);
                //将加密后的字节数组转换成字符串
                string returnData = Convert.ToBase64String(encryptdata);
                return returnData;
            }
    
            /// <summary>
            ///  Md5密钥加密
            /// </summary>
            /// <param name="pToEncrypt">要加密的string字符串</param>
            /// <returns></returns>
            public static string Md5Encrypt_Key(string pToEncrypt)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
                des.Key = Encoding.ASCII.GetBytes(keys);
                des.IV = Encoding.ASCII.GetBytes(keys);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                var s = ret.ToString();
                return s;
            }
    
            /// <summary>
            ///  Md5解密
            /// </summary>
            /// <param name="pToDecrypt">解密string</param>
            /// <returns></returns>
            public static string Md5Decrypt(string pToDecrypt)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
                for (int x = 0; x < pToDecrypt.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }
                des.Key = Encoding.ASCII.GetBytes(_appSecret);
                des.IV = Encoding.ASCII.GetBytes(_appSecret);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return Encoding.Default.GetString(ms.ToArray());
            }
    
            /// <summary>
            /// MD5流加密
            /// </summary>
            /// <param name="inputStream">输入流</param>
            /// <returns></returns>
            public static string GenerateMD5(Stream inputStream)
            {
                using (MD5 mi = MD5.Create())
                {
                    //开始加密
                    byte[] newBuffer = mi.ComputeHash(inputStream);
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < newBuffer.Length; i++)
                    {
                        sb.Append(newBuffer[i].ToString("x2"));
                    }
                    return sb.ToString();
                }
            }
    #endregion
    

    二、Base64加码解码

    • 严格来说,Base64是一种编码,而不是加密,通常Base64编码后字符串会用于传输数据。不过也正是因为Base64编码后字符串具有不可读性;也有人当做加密算法来使用。
            #region Base64加码解码
            /// <summary>
            /// Base64编码,采用utf8编码
            /// </summary>
            /// <param name="strPath">待编码的明文</param>
            /// <returns>Base64编码后的字符串</returns>
            public static string Base64Encrypt(string strPath)
            {
                string returnData;
                Encoding encode = Encoding.UTF8;
                byte[] bytedata = encode.GetBytes(strPath);
                try
                {
                    returnData = Convert.ToBase64String(bytedata, 0, bytedata.Length);
                }
                catch
                {
                    returnData = strPath;
                }
                return returnData;
            }
    
            /// <summary>
            /// Base64解码,采用utf8编码方式解码
            /// </summary>
            /// <param name="strPath">待解码的密文</param>
            /// <returns>Base64解码的明文字符串</returns>
            public static string Base64DesEncrypt(string strPath)
            {
                string returnData;
                byte[] bpath = Convert.FromBase64String(strPath);
                try
                {
                    returnData = Encoding.UTF8.GetString(bpath);
                }
                catch
                {
                    returnData = strPath;
                }
                return returnData;
            }
            #endregion
    

    三、SHA加密解密

    • SHA1加密算法与MD5加密类似,都是不可逆的,只是算法不同。
            /// <summary>
            /// SHA1 加密 
            /// </summary>
            /// <param name="content">需要加密字符串</param>
            /// <param name="encode">指定加密编码</param>
            /// <param name="upperOrLower">大小写格式(大写:X2;小写:x2)默认小写</param> 
            public static string SHA1Encrypt(string content, Encoding encode, string upperOrLower = "x2")
            {
                try
                {
                    var buffer = encode.GetBytes(content);//用指定编码转为bytes数组
                    var data = SHA1.Create().ComputeHash(buffer);
                    var sb = new StringBuilder();
                    foreach (var t in data)
                    {
                        sb.Append(t.ToString(upperOrLower));
                    }
    
                    return sb.ToString();
                }
                catch (Exception ex)
                {
                    return "SHA1加密出错:" + ex.Message;
                }
            }
    
            /// <summary>
            /// SHA256加密
            /// </summary>
            /// <param name="strIN">要加密的string字符串</param>
            /// <returns>SHA256加密之后的密文</returns>
            public static string SHA256Encrypt(string strIN)
            {
                byte[] tmpByte;
                SHA256 sha256 = new SHA256Managed();
                tmpByte = sha256.ComputeHash(GetKeyByteArray(strIN));
    
                StringBuilder rst = new StringBuilder();
                for (int i = 0; i < tmpByte.Length; i++)
                {
                    rst.Append(tmpByte[i].ToString("x2"));
                }
                sha256.Clear();
                return rst.ToString();
            }
            
            /// <summary>
            /// 获取要加密的string字符串字节数组
            /// </summary>
            /// <param name="strKey">待加密字符串</param>
            /// <returns>加密数组</returns>
            private static byte[] GetKeyByteArray(string strKey)
            {
                UTF8Encoding Asc = new UTF8Encoding();
                int tmpStrLen = strKey.Length;
                byte[] tmpByte = new byte[tmpStrLen - 1];
                tmpByte = Asc.GetBytes(strKey);
                return tmpByte;
            }
    

    四、HmacSHA256 Base64加密

            /// <summary>
            /// HmacSHA256 Base64算法,返回的结果始终是32位
            /// </summary>
            /// <param name="message">待加密的明文字符串</param>
            /// <returns>HmacSHA256算法加密之后的密文</returns>
            public static string HmacSHA256(string message)
            {
                byte[] keyByte = Encoding.GetEncoding("utf-8").GetBytes(_appSecret);
                byte[] messageBytes = Encoding.GetEncoding("utf-8").GetBytes(message);
                using (var hmacsha256 = new HMACSHA256(keyByte))
                {
                    byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                    return Convert.ToBase64String(hashmessage);
                }
            }
    

    五、DES加密解密

    • DES(Data Encryption Standard)是目前最为流行的加密算法之一。DES是对称的,也就是说它使用同一个密钥来加密和解密数据。
    • DES还是一种分组加密算法,该算法每次处理固定长度的数据段,称之为分组。
    • DES加密算法对密钥有要求,必须是8个字符,如12345678这样的。
            #region  DES加密解密
            /// <summary>
            /// DES加密操作
            /// </summary>
            /// <param name="normalTxt">需要加密的明文字符串</param>
            /// <returns>返回DES加密的密文字符串</returns>
            public static string DesEncrypt(string normalTxt)
            {
                DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
                int i = cryptoProvider.KeySize;
                MemoryStream ms = new MemoryStream();
                CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(_KEY, _IV), CryptoStreamMode.Write);
                StreamWriter sw = new StreamWriter(cst);
                sw.Write(normalTxt);
                sw.Flush();
                cst.FlushFinalBlock();
                sw.Flush();
    
                string strRet = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
                return strRet;
            }
    
            /// <summary>
            /// DES解密操作
            /// </summary>
            /// <param name="securityTxt">需要解密的密文字符串</param>
            /// <returns>返回DES解密之后的明文字符串</returns>
            public static string DesDecrypt(string securityTxt)//解密  
            {
                byte[] byEnc;
                try
                {
                    securityTxt.Replace("_%_", "/");
                    securityTxt.Replace("-%-", "#");
                    byEnc = Convert.FromBase64String(securityTxt);
                }
                catch
                {
                    return null;
                }
                DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
                MemoryStream ms = new MemoryStream(byEnc);
                CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(_KEY, _IV), CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cst);
                return sr.ReadToEnd();
            }
    #endregion
    

    六、AES加密解密

    • 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)
    #region AES加密解密
            /// <summary>
            ///  AES base64 加密算法;Key 为16位
            /// </summary>
            /// <param name="Data">需要加密的字符串</param>
            /// <returns></returns>
            public static string RST_AesEncrypt_Base64(string Data)
            {
                if (string.IsNullOrEmpty(Data))
                {
                    return null;
                }
                if (string.IsNullOrEmpty(Key))
                {
                    return null;
                }
                string Vector = Key.Substring(0, 16);
                Byte[] plainBytes = Encoding.UTF8.GetBytes(Data);
                Byte[] bKey = new Byte[32];
                Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
                Byte[] bVector = new Byte[16];
                Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
                Byte[] Cryptograph = null; // 加密后的密文  
                Rijndael Aes = Rijndael.Create();
                //add 
                Aes.Mode = CipherMode.CBC;//兼任其他语言的des
                Aes.BlockSize = 128;
                Aes.Padding = PaddingMode.PKCS7;
                //add end
                try
                {
                    // 开辟一块内存流  
                    using (MemoryStream Memory = new MemoryStream())
                    {
                        // 把内存流对象包装成加密流对象  
                        using (CryptoStream Encryptor = new CryptoStream(Memory,
                         Aes.CreateEncryptor(bKey, bVector),
                         CryptoStreamMode.Write))
                        {
                            // 明文数据写入加密流  
                            Encryptor.Write(plainBytes, 0, plainBytes.Length);
                            Encryptor.FlushFinalBlock();
    
                            Cryptograph = Memory.ToArray();
                        }
                    }
                }
                catch
                {
                    Cryptograph = null;
                }
                return Convert.ToBase64String(Cryptograph);
            }
    
            /// <summary>
            ///  AES base64 解密算法;Key为16位
            /// </summary>
            /// <param name="Data">需要解密的字符串</param>
            /// <param name="Key">Key为16位 密钥</param>
            /// <returns></returns>
            public static string RST_AesDecrypt_Base64(string Data)
            {
                try
                {
                    if (string.IsNullOrEmpty(Data))
                    {
                        return null;
                    }
                    if (string.IsNullOrEmpty(Key))
                    {
                        return null;
                    }
                    string Vector = Key.Substring(0, 16);
                    Byte[] encryptedBytes = Convert.FromBase64String(Data);
                    Byte[] bKey = new Byte[32];
                    Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
                    Byte[] bVector = new Byte[16];
                    Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
                    Byte[] original = null; // 解密后的明文  
                    Rijndael Aes = Rijndael.Create();
                    //add 
                    Aes.Mode = CipherMode.CBC;//兼任其他语言的des
                    Aes.BlockSize = 128;
                    Aes.Padding = PaddingMode.PKCS7;
                    //add end
                    try
                    {
                        // 开辟一块内存流,存储密文  
                        using (MemoryStream Memory = new MemoryStream(encryptedBytes))
                        {
                            //把内存流对象包装成加密流对象  
                            using (CryptoStream Decryptor = new CryptoStream(Memory,
                            Aes.CreateDecryptor(bKey, bVector),
                            CryptoStreamMode.Read))
                            {
                                // 明文存储区  
                                using (MemoryStream originalMemory = new MemoryStream())
                                {
                                    Byte[] Buffer = new Byte[1024];
                                    Int32 readBytes = 0;
                                    while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)
                                    {
                                        originalMemory.Write(Buffer, 0, readBytes);
                                    }
                                    original = originalMemory.ToArray();
                                }
                            }
                        }
                    }
                    catch
                    {
                        original = null;
                    }
                    return Encoding.UTF8.GetString(original);
                }
                catch { return null; }
            }
    
            /// <summary>
            /// 密钥16位或者32位的AES base64加密
            /// </summary>
            /// <param name="value">需要进行加密的明文字符串</param>
            /// <param name="key">16位或者32位的密钥</param>
            /// <param name="iv">16位以上的向量;默认为:"*Gc_Yy_Cq_@_Ztl_99*"</param>
            /// <returns>AES加密之后的密文</returns>
            public static string AesEncrypt(string value, string key, string iv = "")
            {
                if (string.IsNullOrEmpty(value)) return string.Empty;
                if (string.IsNullOrEmpty(key))
                {
                    key = Key;
                }
                if (key.Length < 16) throw new Exception("指定的密钥长度不能少于16位。");
                if (key.Length > 32) throw new Exception("指定的密钥长度不能多于32位。");
                if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密钥长度不明确。");
                if (string.IsNullOrEmpty(iv))
                {
                    iv = vector;
                }
                if (!string.IsNullOrEmpty(iv))
                {
                    if (iv.Length < 16) throw new Exception("指定的向量长度不能少于16位。");
                }
    
                var _keyByte = Encoding.UTF8.GetBytes(key);
                var _valueByte = Encoding.UTF8.GetBytes(value);
                using (var aes = new RijndaelManaged())
                {
                    aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));
                    aes.Key = _keyByte;
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;
                    var cryptoTransform = aes.CreateEncryptor();
                    var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);
                    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
                }
            }
    
            /// <summary>
            /// 密钥16位或者32位的AES base64解密
            /// </summary>
            /// <param name="value">需要解密的密文</param>
            /// <param name="key">16位或者32位的密钥需和加密时的密钥保持一致</param>
            /// <param name="iv">16位以上的向量需和加密时的向量保持一致;默认为:"*Gc_Yy_Cq_@_Ztl_99*"</param>
            /// <returns>AES解密之后的明文</returns>
            public static string AesDecrypt(string value, string key, string iv = "")
            {
                if (string.IsNullOrEmpty(value)) return string.Empty;
                if (string.IsNullOrEmpty(key))
                {
                    key = Key;
                }
                if (key.Length < 16) throw new Exception("指定的密钥长度不能少于16位。");
                if (key.Length > 32) throw new Exception("指定的密钥长度不能多于32位。");
                if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密钥长度不明确。");
                if (string.IsNullOrEmpty(iv))
                {
                    iv = vector;
                }
                if (!string.IsNullOrEmpty(iv))
                {
                    if (iv.Length < 16) throw new Exception("指定的向量长度不能少于16位。");
                }
    
                var _keyByte = Encoding.UTF8.GetBytes(key);
                var _valueByte = Convert.FromBase64String(value);
                using (var aes = new RijndaelManaged())
                {
                    aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));
                    aes.Key = _keyByte;
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;
                    var cryptoTransform = aes.CreateDecryptor();
                    var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);
                    return Encoding.UTF8.GetString(resultArray);
                }
            }
            #endregion
    

    七、RSA加密解密:采用公钥,私钥的模式

    • RSA加密采用公钥加密,私钥解密的模式或者私钥加密,公钥解密的模式。Https的数字证书也是使用这种模式加密的。
    • 但是RSA加密有个特点,就是他对被加密的字符串有长度限制;待加密的字节数不能超过密钥的长度值除以8再减去11(即:RSACryptoServiceProvider.KeySize / 8 - 11,而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)。注:该长度指的是byte[]数组的长度,而不是字符串的长度,简单来说,就是被加密字符串不能太长。
            #region RSA加密解密:采用公钥,私钥的模式
    
            #region 私钥加密,公钥解密
    
            /// <summary>
            /// RSA私钥加密
            /// </summary>
            /// <param name="privateKey">Java格式的RSA私钥 base64格式</param>
            /// <param name="contentData">待加密的数据;调用方法Encoding.GetEncoding("UTF-8").GetBytes(contentData)</param>
            /// <param name="algorithm">加密算法</param>
            /// <returns>RSA私钥加密之后的密文</returns>
            public static string EncryptWithPrivateKey(string privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
            {
                return Convert.ToBase64String(EncryptWithPrivateKey(Convert.FromBase64String(privateKey), contentData, algorithm));
            }
    
            private static byte[] Transform(AsymmetricKeyParameter key, byte[] contentData, string algorithm, bool forEncryption)
            {
                var c = CipherUtilities.GetCipher(algorithm);
                c.Init(forEncryption, new ParametersWithRandom(key));
                return c.DoFinal(contentData);
            }
    
            /// <summary>
            /// RSA私钥加密
            /// </summary>
            /// <param name="privateKey">Java格式的RSA私钥</param>
            /// <param name="contentData">待加密的数据;调用方法Encoding.GetEncoding("UTF-8").GetBytes(contentData)</param>
            /// <param name="algorithm">加密算法</param>
            /// <returns>RSA私钥加密之后的密文</returns>
            public static byte[] EncryptWithPrivateKey(byte[] privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
            {
                RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKey);
                return Transform(privateKeyParam, contentData, algorithm, true);
            }
    
            /// <summary>
            /// RSA公钥解密
            /// </summary>
            /// <param name="publicKey">Java格式的RSA公钥  base64格式</param>
            /// <param name="content">待解密数据 base64格式</param>
            /// <param name="encoding">解密出来的数据编码格式,默认UTF-8</param>
            /// <param name="algorithm">加密算法</param>
            /// <returns>RSA私钥解密之后的明文</returns>
            public static string DecryptWithPublicKey(string publicKey, string content, string encoding = "UTF-8", string algorithm = "RSA/ECB/PKCS1Padding")
            {
                return Encoding.GetEncoding(encoding).GetString(DecryptWithPublicKey(Convert.FromBase64String(publicKey), Convert.FromBase64String(content), algorithm));
            }
    
            /// <summary>
            /// RSA公钥解密
            /// </summary>
            /// <param name="publicKey">Java格式的RSA公钥</param>
            /// <param name="contentData">待解密数据</param>
            /// <param name="algorithm">加密算法</param>
            /// <returns>RSA私钥解密之后的明文</returns>
            public static byte[] DecryptWithPublicKey(byte[] publicKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
            {
                RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKey);
                return Transform(publicKeyParam, contentData, algorithm, false);
            }
            #endregion
    
            #region 公钥加密,私钥解密
    
            /// <summary>
            /// RSA公钥加密
            /// </summary>
            /// <param name="xmlPublicKey">加密公钥;为空则默认系统公钥</param>
            /// <param name="enptStr">需要加密的明文字符串</param>
            /// <param name="encoding">编码格式;默认:UTF-8</param>
            /// <returns>RSA公钥加密的密文</returns>
            public static string RSAEncrypt_Public(string xmlPublicKey, string enptStr, string encoding = "UTF-8")
            {
                if (string.IsNullOrEmpty(xmlPublicKey))
                {
                    xmlPublicKey = _publicKey;
                }
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    byte[] cipherbytes;
                    rsa.FromXmlString(xmlPublicKey);
                    cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(enptStr), false);
                    return Convert.ToBase64String(cipherbytes);
                }
            }
    
            /// <summary>
            /// RSA私钥解密
            /// </summary>
            /// <param name="xmlPrivateKey">解密私钥;为空则默认系统公钥</param>
            /// <param name="enptStr">需要加密的明文字符串</param>
            /// <param name="encoding">编码格式;默认:UTF-8</param>
            /// <returns>RSA私钥解密的明文</returns>
            public static string RSADecrypt_Private(string xmlPrivateKey, string enptStr, string encoding = "UTF-8")
            {
                if (string.IsNullOrEmpty(xmlPrivateKey))
                {
                    xmlPrivateKey = _privateKey;
                }
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    byte[] cipherbytes;
                    rsa.FromXmlString(xmlPrivateKey);
                    cipherbytes = rsa.Decrypt(Convert.FromBase64String(enptStr), false);
                    return Encoding.GetEncoding(encoding).GetString(cipherbytes);
                }
            }
            #endregion
    
            #region 使用同一容器的名称进行RSA加密解密
    
            /// <summary>
            /// 进行 RSA 加密
            /// </summary>
            /// <param name="sourceStr">源字符串</param>
            /// <returns>加密后字符串</returns>
            public static string RsaEncrypt(string sourceStr)
            {
                Param = new CspParameters();
                //密匙容器的名称,保持加密解密一致才能解密成功
                Param.KeyContainerName = "Navis";
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(Param))
                {
                    //将要加密的字符串转换成字节数组
                    byte[] plaindata = Encoding.Default.GetBytes(sourceStr);
                    //通过字节数组进行加密
                    byte[] encryptdata = rsa.Encrypt(plaindata, false);
                    //将加密后的字节数组转换成字符串
                    return Convert.ToBase64String(encryptdata);
                }
            }
    
            /// <summary>
            /// 通过RSA 加密方式进行解密
            /// </summary>
            /// <param name="codingStr">加密字符串</param>
            /// <returns>解密后字符串</returns>
            public static string RsaDesEncrypt(string codingStr)
            {
                Param = new CspParameters();
                Param.KeyContainerName = "Navis";
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(Param))
                {
                    byte[] encryptdata = Convert.FromBase64String(codingStr);
                    byte[] decryptdata = rsa.Decrypt(encryptdata, false);
                    return Encoding.Default.GetString(decryptdata);
                }
            }
            #endregion
    
            #region RSA分段加密:待加密的字符串拆开,每段长度都小于等于限制长度,然后分段加密
    
            /// <summary>
            /// RSA分段加密
            /// </summary>
            /// <param name="xmlPublicKey">RSA C#公钥</param>
            /// <param name="enptStr">需要进行RSA加密的长字符串</param>
            /// <returns>返回RSA加密后的密文</returns>
            public static String SubRSAEncrypt(string xmlPublicKey, string enptStr)
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPublicKey);
                Byte[] bytes = Encoding.Default.GetBytes(enptStr);
                int MaxBlockSize = provider.KeySize / 8 - 11;  //加密块最大长度限制
    
                if (bytes.Length <= MaxBlockSize)
                    return Convert.ToBase64String(provider.Encrypt(bytes, false));
    
                using (MemoryStream PlaiStream = new MemoryStream(bytes))
                using (MemoryStream CrypStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
    
                    while (BlockSize > 0)
                    {
                        Byte[] ToEncrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);
    
                        Byte[] Cryptograph = provider.Encrypt(ToEncrypt, false);
                        CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
    
                        BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
                    }
    
                    return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
                }
    
            }
    
            /// <summary>
            /// RSA分段解密,应对长字符串
            /// </summary>
            /// <param name="xmlPrivateKey">RSA C#私钥</param>
            /// <param name="enptStr">需要解密的长字符串</param>
            /// <returns>返回RSA分段解密的明文</returns>
            public static String SubRSADecrypt(string xmlPrivateKey, string enptStr)
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPrivateKey);
                Byte[] bytes = Convert.FromBase64String(enptStr);
                int MaxBlockSize = provider.KeySize / 8;  //解密块最大长度限制
    
                if (bytes.Length <= MaxBlockSize)
                    return Encoding.Default.GetString(provider.Decrypt(bytes, false));
    
                using (MemoryStream CrypStream = new MemoryStream(bytes))
                using (MemoryStream PlaiStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
    
                    while (BlockSize > 0)
                    {
                        Byte[] ToDecrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);
    
                        Byte[] Plaintext = provider.Decrypt(ToDecrypt, false);
                        PlaiStream.Write(Plaintext, 0, Plaintext.Length);
    
                        BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
                    }
    
                    return Encoding.Default.GetString(PlaiStream.ToArray());
                }
            }
            #endregion
    
            #endregion
    

    本文来自博客园,作者:TomLucas,转载请注明原文链接:https://www.cnblogs.com/lucasDC/p/15046822.html

  • 相关阅读:
    linux的性能优化
    linux日志分析
    rsyslog日志服务的配置文件分析
    Unix 入门
    Linux常用快捷键
    Linux常用命令大全
    ueditor 实现ctrl+v粘贴图片并上传、word粘贴带图片
    本地图文直接复制到WordPress编辑器中
    本地图文直接复制到Blog编辑器中
    http大文件上传(切片)
  • 原文地址:https://www.cnblogs.com/lucasDC/p/15046822.html
Copyright © 2020-2023  润新知