• C# 加密总结 一些常见的加密方法


    C# 加密总结 一些常见的加密方法

    一 散列数据 代码如下:

    private static string CalculateSHA512Hash(string input)
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                SHA512Managed sha512 = new SHA512Managed();
                byte[] outputBytes = sha512.ComputeHash(inputBytes);
                return Convert.ToBase64String(outputBytes);
            }

     原始散列对于彩虹表来说也存在漏洞,在彩虹表中,表内的每一条记录都是一串明文对应一种加密算法生成的一串密文。加盐就是指在密码中加入一个盐,这样可以提高密码散列的安全性。修改后的代码如下:

    private static string CalculateSHA512Hash(string input,string salt)
          {
              byte[] saltBytes = Convert.FromBase64String(salt);
              byte[] inputBytes = Encoding.UTF8.GetBytes(input);
              byte[] inputWithSaltBytes = new byte[saltBytes.Length + inputBytes.Length];
              Array.Copy(inputBytes, 0, inputWithSaltBytes, 0, inputBytes.Length);
              Array.Copy(saltBytes, 0, inputWithSaltBytes, inputBytes.Length, saltBytes.Length);
              SHA512Managed sha512 = new SHA512Managed();
              byte[] outputBytes = sha512.ComputeHash(inputWithSaltBytes);
              return Convert.ToBase64String(outputBytes);
          }
          private static string GetSalt(int minSaltSize, int maxSaltSize)
          {
              Random random = new Random();
              int saltSize = random.Next(minSaltSize, maxSaltSize);
              byte[] saltBytes = new byte[saltSize];
              RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
              rng.GetNonZeroBytes(saltBytes);
              return Convert.ToBase64String(saltBytes);
          }

     二 对称加密

    private static string Encrypt(string input, byte[] key, byte[] iv)
          {
              byte[] inputBytes = Encoding.UTF8.GetBytes(input);
              RijndaelManaged rijndael = new RijndaelManaged();
              ICryptoTransform transform = rijndael.CreateEncryptor(key, iv);
              byte[] encrytData = null;
              using (MemoryStream outputStream = new MemoryStream())
              {
                  using (CryptoStream inputStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write))
                  {
                      inputStream.Write(inputBytes, 0, inputBytes.Length);
                      inputStream.FlushFinalBlock();
                      encrytData = outputStream.ToArray();
                  }
     
              }
              return Convert.ToBase64String(encrytData);
          }
          private static string Decrypt(string input, byte[] key, byte[] iv)
          {
              byte[] inputBytes=Convert.FromBase64String(input);
              RijndaelManaged rijndael = new RijndaelManaged();
              ICryptoTransform transform = rijndael.CreateDecryptor(key, iv);
              byte[] decryptByte;
              using (MemoryStream outputStream=new MemoryStream())
              {
                  using (CryptoStream inputStream=new CryptoStream(outputStream,transform,CryptoStreamMode.Write))
                  {
                      inputStream.Write(inputBytes, 0, inputBytes.Length);
                      inputStream.FlushFinalBlock();
                      decryptByte = outputStream.ToArray();
                  }
              }
              return Encoding.UTF8.GetString(decryptByte);
          }
          private static void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt, SymmetricAlgorithm symmetricAlgorithm,
              ref byte[] key, ref byte[] iv)
          {
              Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
              key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
              iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
          }
          private static string GetSalt(int minSaltSize, int maxSaltSize)
          {
              Random random = new Random();
              int saltSize = random.Next(minSaltSize, maxSaltSize);
              byte[] saltBytes = new byte[saltSize];
              RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
              rng.GetNonZeroBytes(saltBytes);
              return Convert.ToBase64String(saltBytes);
          }

     调用方式:
                byte[] salt = Convert.FromBase64String(GetSalt(9, 18));
                string password = "Password";
                byte[] key=new byte[0];
                byte[] iv = new byte[0];
                GetKeyAndIVFromPasswordAndSalt(password,salt, new RijndaelManaged(), ref key, ref iv);
                string input = "Wrox Press";
                string encrytText = Encrypt(input, key, iv);
                Console.WriteLine(encrytText);
                string decryptText=Decrypt(encrytText,key,iv);
                Console.WriteLine(decryptText);

    只是简单的加密和解密数据是不够的,我们还需要确保数据不被改变,我们可以创建一个消息认证代码来生成一个加密的散列。

    private static string GenerateMac(string input, byte[] key)
          {
              HMACSHA512 hmac = new HMACSHA512(key);
              byte[] data= hmac.ComputeHash(Convert.FromBase64String(input));
              return Convert.ToBase64String(data);
          }
          static bool IsMacValid(string input, byte[] key, string savedMac)
          {
              string recalculateMac = GenerateMac(input, key);
              return recalculateMac.Equals(savedMac);
          }

     例如我们对数据库中LicenseNumber加密,那么我们就必须修改表结构,修改后如图:

    非对称加密:

    private static string Encrypt(string input, string publickey)
           {
               RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
               rsa.FromXmlString(publickey);
               byte[] encryptData = rsa.Encrypt(Encoding.UTF8.GetBytes(input), true);
               return Convert.ToBase64String(encryptData);
           }
           private static string Decrypt(string input, string privatekey)
           {
               RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
               rsa.FromXmlString(privatekey);
               byte[] dencryptData = rsa.Decrypt(Convert.FromBase64String(input), true);
               return Encoding.UTF8.GetString(dencryptData);
           }
           private static void GetkeyXml(out string publicKey, out string privateKey)
           {
               RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
               publicKey = rsa.ToXmlString(false);
               privateKey = rsa.ToXmlString(true);
           }

     证书加密:

    static byte[] SignData(byte[] clearText, X509Certificate2 signingCertificate)
          {
              ContentInfo contentInfo = new ContentInfo(clearText);
              CmsSigner signer = new CmsSigner(signingCertificate);
              SignedCms signedCms = new SignedCms(contentInfo);
              signedCms.ComputeSignature(signer);
              return signedCms.Encode();
          }
          static byte[] ValidateSignatureAndExtractContent(byte[] signedCmsAsBytes, ICollection<string> signingSubjects)
          {
              SignedCms signedCms = new SignedCms();
              signedCms.Decode(signedCmsAsBytes);
              signedCms.CheckSignature(true);
              foreach (SignerInfo signerInfo in signedCms.SignerInfos)
              {
                  X509Certificate2 signingCertificate = signerInfo.Certificate;
                  signingSubjects.Add(signingCertificate.Subject);
              }
              return signedCms.ContentInfo.Content;
          }
          static byte[] EncryptWithCertificate(byte[] clearText, X509Certificate2 certificate)
          {
              ContentInfo contentInfo = new ContentInfo(clearText);
              EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);
              CmsRecipient recipient = new CmsRecipient(certificate);
              envelopedCms.Encrypt(recipient);
              return envelopedCms.Encode();
          }
          static byte[] DecryptWithCertificate(byte[] cipherText)
          {
              EnvelopedCms envelopedCms = new EnvelopedCms();
              envelopedCms.Decode(cipherText);
              envelopedCms.Decrypt();
              return envelopedCms.ContentInfo.Content;
          }
          static X509Certificate2 LoadCertificateFromFile(string filename)
          {
              X509Certificate2 certificate = new X509Certificate2();
              certificate.Import(ReadBinaryFile(filename));
              return certificate;
          }
          static byte[] ReadBinaryFile(string filename)
          {
              FileStream f = new FileStream(filename, FileMode.Open, FileAccess.Read);
              int size = (int)f.Length;
              byte[] data = new byte[size];
              size = f.Read(data, 0, size);
              f.Close();
              return data;
          }
          private static X509Certificate2 GetCertificateBySubjectName(string subjectName)
          {
     
              X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                  myStore.Open(OpenFlags.ReadOnly);
                  X509Certificate2Collection certificateCollection = myStore.Certificates.Find(X509FindType.FindBySubjectName, subjectName, true);
                  X509Certificate2 myCertificate = certificateCollection[0];
                  if (myStore != null)
                      myStore.Close();
                  return myCertificate;
          }

     调用方式:

     string input = "Wrox Press";
                byte[] clearTextAsBytes = Encoding.UTF8.GetBytes(input);
                X509Certificate2 serverPublicKeyCertificate = LoadCertificateFromFile("IISExpress.cer");
                X509Certificate2 signingCertificate = GetCertificateBySubjectName("test");
                byte[] signedClearText = SignData(clearTextAsBytes, signingCertificate);
                byte[] encryptedAndSignedData = EncryptWithCertificate(signedClearText, serverPublicKeyCertificate);

                byte[] encodedUnencryptedCms = DecryptWithCertificate(encryptedAndSignedData);
                List<string> signingSubjects = new List<string>();
                byte[] receivedClearText = ValidateSignatureAndExtractContent(encodedUnencryptedCms, signingSubjects);
                string unecnryptedString = Encoding.UTF8.GetString(receivedClearText);
                Console.ReadLine();

    我的计算机是win8,这里并没有用什么企业级证书,作为测试,我是用win8中IIS来创建自签名证书,然后用mmc来管理证书(http://softbbs.zol.com.cn/1/20_1370.html),所以以上的GetCertificateBySubjectName方法需要修改如下:

      private static X509Certificate2 GetCertificateBySubjectName(string subjectName)
            {
                X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                myStore.Open(OpenFlags.ReadOnly);

                X509Certificate2Collection certificateCollection = myStore.Certificates.Find(X509FindType.FindBySubjectName, subjectName, true);
                X509Certificate2 myCertificate;
                if (certificateCollection.Count > 0)
                {
                    myCertificate = certificateCollection[0];
                }
                else
                {
                    X509Certificate2[] array = new X509Certificate2[myStore.Certificates.Count];
                    myStore.Certificates.CopyTo(array, 0);
                    myCertificate = array.FirstOrDefault(x => x.FriendlyName.Equals(subjectName));
                }
                if (myStore != null)
                    myStore.Close();
                return myCertificate;
            }

     
     
     
    标签: C#
  • 相关阅读:
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    leetcode刷题笔记 260题 只出现一次的数字 III
    leetcode刷题笔记 241题 为运算表达式设计优先级
    leetcode刷题笔记 258题 各位相加
    leetcode刷题笔记 257题 二叉树的所有路径
    leetcode刷题笔记 242题 有效的字母异位词
    leetcode刷题笔记 240题 搜索二维矩阵 II
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3174965.html
Copyright © 2020-2023  润新知