C#对称加密和非对称加密(AES和RSA)

看看我

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace 加密
{
    class Program
    {
        static void Main(string[] args)
        {
            //RSA
            //var dicKey = RSAHelper.GetKey();
            //Console.WriteLine($"{dicKey["PublicKey"]}\r\n{dicKey["PrivateKey"]}");
            //string strText = "aaabbbcc";
            //Console.WriteLine("要加密的字符串是:{0}", strText);
            //string str1 = RSAHelper.Encrypt(strText, dicKey["PublicKey"]);
            //Console.WriteLine("加密后的字符串:{0}", str1);
            //string str2 = RSAHelper.Decrypt(str1, dicKey["PrivateKey"]);
            //Console.WriteLine("解密后的字符串:{0}", str2);

            //AES
            string password = "abcAE#$M&*987";
            Console.WriteLine($"原始密码为:{password} ");

            // AES的key支持128位,最大支持256位。256位需要32个字节。
            //string key = "1234567890qwerty1234567890qwerty";//32字节
            string key = AESHelper.GetRandomStr(32, true, true, true, true);

            var EncryptStr = AESHelper.Encrypt(key, password);
            Console.WriteLine($"使用密钥:{key} 为原密码:{password} 加密");
            Console.WriteLine($"得到密文:{EncryptStr}");

            Console.WriteLine($"使用密钥:{key} 为密文:{EncryptStr} 解密");
            var realPwd = AESHelper.Decrypt(key, EncryptStr);
            Console.WriteLine($"得到原密码:{realPwd}");
        }
    }

    public static class RSAHelper
    {
        /// <summary>
        /// 使用公钥加密
        /// </summary>
        /// <returns></returns>
        public static string Encrypt(string text, string publicKey)
        {
            byte[] byteEncrypt;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(Convert.FromBase64String(publicKey));
                byte[] byteText = Encoding.UTF8.GetBytes(text);
                byteEncrypt = rsa.Encrypt(byteText, false);
            }
            return Convert.ToBase64String(byteEncrypt);
        }

        /// <summary>
        /// 私钥解密
        /// </summary>
        /// <param name="strEntryText"></param>
        /// <param name="strPrivateKey"></param>
        /// <returns></returns>
        public static string Decrypt(string encryptText, string privateKey)
        {
            byte[] byteText;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(Convert.FromBase64String(privateKey));
                byte[] byteEncrypt = Convert.FromBase64String(encryptText);
                byteText = rsa.Decrypt(byteEncrypt, false);
            }
            return Encoding.UTF8.GetString(byteText);
        }

        /// <summary>
        /// 获取公钥和私钥
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, string> GetKey()
        {
            Dictionary<string, string> dicKey = new Dictionary<string, string>();
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                string public_Key = Convert.ToBase64String(rsa.ExportCspBlob(false));
                string private_Key = Convert.ToBase64String(rsa.ExportCspBlob(true));
                dicKey.Add("PublicKey", public_Key);
                dicKey.Add("PrivateKey", private_Key);
            }
            return dicKey;
        }
    }

    public static class AESHelper
    {
        //为什么要用base64,因为得到的密文是byte[],所以默认用base64转成str方便查看
        // AES 加密的初始化向量,加密解密需设置相同的值。需要是16字节
        public static byte[] AES_IV = Encoding.UTF8.GetBytes("1234567890123458");

        /// <summary>
        ///  加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="data">要被加密的明文</param>
        /// <returns>密文base64</returns>
        public static string Encrypt(string key, string data)
        {
            using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
            {
                aesAlg.Key = Encoding.UTF8.GetBytes(key);
                aesAlg.IV = AES_IV;
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(data);
                        }
                        byte[] bytes = msEncrypt.ToArray();
                        return Convert.ToBase64String(bytes);
                    }
                }
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="encryptData">密文</param>
        /// <returns>明文</returns>
        public static string Decrypt(string key, string encryptData)
        {
            byte[] inputBytes = Convert.FromBase64String(encryptData);
            using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
            {
                aesAlg.Key = Encoding.UTF8.GetBytes(key);
                aesAlg.IV = AES_IV;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                using (MemoryStream msEncrypt = new MemoryStream(inputBytes))
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srEncrypt = new StreamReader(csEncrypt))
                        {
                            return srEncrypt.ReadToEnd();
                        }
                    }
                }
            }
        }

        #region 生成指定长度的随机字符串
        /// <summary>
        /// 生成指定长度的随机字符串
        /// </summary>
        /// <param name="intLength">随机字符串长度</param>
        /// <param name="booNumber">生成的字符串中是否包含数字</param>
        /// <param name="booSign">生成的字符串中是否包含符号</param>
        /// <param name="booSmallword">生成的字符串中是否包含小写字母</param>
        /// <param name="booBigword">生成的字符串中是否包含大写字母</param>
        /// <returns></returns>
        public static string GetRandomStr(int intLength, bool booNumber, bool booSign, bool booSmallword, bool booBigword)
        {
            //定义
            Random ranA = new Random();
            int intResultRound = 0;
            int intA = 0;
            string strB = "";

            while (intResultRound < intLength)
            {
                //生成随机数A,表示生成类型
                //1=数字,2=符号,3=小写字母,4=大写字母

                intA = ranA.Next(1, 5);

                //如果随机数A=1,则运行生成数字
                //生成随机数A,范围在0-10
                //把随机数A,转成字符
                //生成完,位数+1,字符串累加,结束本次循环

                if (intA == 1 && booNumber)
                {
                    intA = ranA.Next(0, 10);
                    strB = intA.ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }

                //如果随机数A=2,则运行生成符号
                //生成随机数A,表示生成值域
                //1:33-47值域,2:58-64值域,3:91-96值域,4:123-126值域

                if (intA == 2 && booSign)
                {
                    intA = ranA.Next(1, 5);

                    //如果A=1
                    //生成随机数A,33-47的Ascii码
                    //把随机数A,转成字符
                    //生成完,位数+1,字符串累加,结束本次循环

                    if (intA == 1)
                    {
                        intA = ranA.Next(33, 48);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=2
                    //生成随机数A,58-64的Ascii码
                    //把随机数A,转成字符
                    //生成完,位数+1,字符串累加,结束本次循环

                    if (intA == 2)
                    {
                        intA = ranA.Next(58, 65);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=3
                    //生成随机数A,91-96的Ascii码
                    //把随机数A,转成字符
                    //生成完,位数+1,字符串累加,结束本次循环

                    if (intA == 3)
                    {
                        intA = ranA.Next(91, 97);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=4
                    //生成随机数A,123-126的Ascii码
                    //把随机数A,转成字符
                    //生成完,位数+1,字符串累加,结束本次循环

                    if (intA == 4)
                    {
                        intA = ranA.Next(123, 127);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                }

                //如果随机数A=3,则运行生成小写字母
                //生成随机数A,范围在97-122
                //把随机数A,转成字符
                //生成完,位数+1,字符串累加,结束本次循环

                if (intA == 3 && booSmallword)
                {
                    intA = ranA.Next(97, 123);
                    strB = ((char)intA).ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }

                //如果随机数A=4,则运行生成大写字母
                //生成随机数A,范围在65-90
                //把随机数A,转成字符
                //生成完,位数+1,字符串累加,结束本次循环

                if (intA == 4 && booBigword)
                {
                    intA = ranA.Next(65, 89);
                    strB = ((char)intA).ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }
            }
            return strB;

        }
        #endregion
    }

}

posted @ 2021-04-15 15:20  vvull  阅读(341)  评论(0编辑  收藏  举报