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加密,那么我们就必须修改表结构,修改后如图:

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

非对称加密

 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#)