• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            流量統(tǒng)計(jì):
            Rixu Blog (日需博客)
            日需博客,每日必需來(lái)踩踩哦..
            posts - 108,comments - 54,trackbacks - 0

            1.1.1 摘要

                    相信許多人都使用過(guò).NET提供的加密算法,而且在使用的過(guò)程我們必須了解每種加密算法的特點(diǎn)(對(duì)稱或非對(duì)稱,密鑰長(zhǎng)度和初始化向量等等)。我也看到過(guò)很多人寫(xiě)過(guò).NET中加密算法總結(jié),但我發(fā)現(xiàn)個(gè)別存在一些問(wèn)題,很多人喜歡羅列每種加密算法的具體實(shí)現(xiàn),假設(shè)我們要求實(shí)現(xiàn)AES和Triple DES加密算法,的確可以很多地分別給出它們的具體實(shí)現(xiàn)。

                   那我們真的有必要給出每個(gè)加密算法的具體實(shí)現(xiàn)嗎?而且這樣的設(shè)計(jì)不符合OOP設(shè)計(jì)思想,最重要的是我們要維護(hù)多個(gè)加密算法啊!OK接下來(lái)讓我們實(shí)行一個(gè)可擴(kuò)展和好維護(hù)的加密算法Helper。

             

            1.1.2 正文

                   encrypts2

            圖1 Hash加密算法繼承層次

             

                   從上面的繼承層次我們可以知道.NET中提供七種Hash加密算法,它們都繼承于抽象類HashAlgorithm,而且我們經(jīng)常使用MD5,SHA1和SHA256等加密算法。下面我們將給出MD5和SHA1的實(shí)現(xiàn)。

             

            encrypts1

            圖2 對(duì)稱加密算法繼承層次

             

                   從上面的繼承層次我們可以知道.NET中提供五種對(duì)稱加密算法,它們都繼承于抽象類SymmetricAlgorithm,下面我們將給出它們的通用實(shí)現(xiàn)。

             

            encrypts3

            圖3 非對(duì)稱加密算法繼承層次

             

                   從上面的繼承層次我們可以知道.NET中提供四種非對(duì)稱加密算法,它們都繼承于抽象類AsymmetricAlgorithm,下面我們將給出RSA實(shí)現(xiàn)。

                   除了以上加密算法,.NET還提供了很多其他類型的加密,這里我們主要介紹一些常用的加密算法,如果大家需要了解的話可以查閱MSDN。OK接下來(lái)讓我們給出Hash加密算法的實(shí)現(xiàn)吧。

             

            Hash加密算法

                  在給出具體的算法實(shí)現(xiàn)之前,首先讓我們回憶一下什么是Hash加密算法?

                  Hash加密是通過(guò)使用hash函數(shù)對(duì)要加密的信息進(jìn)行加密,然后生成相應(yīng)的哈希值,那么我們可以定義一個(gè)hash()函數(shù),要加密的信息m和加密后的哈希值h。

            clip_image001

             

                  我們對(duì)信息m1和m2進(jìn)行hash加密,就可以獲取相應(yīng)哈希值hash(m1)和hash(m2)。

            clip_image002

             

                   如果信息m1=m2那么,那么將得到同一的哈希地址,但是信息m1!=m2也可能得到同一哈希地址,那么就發(fā)生了哈希沖突(collision),在一般的情況下,哈希沖突只能盡可能地減少,而不能完全避免。當(dāng)發(fā)生哈希沖突時(shí),我們要使用沖突解決方法,而主要的沖突解決方法:開(kāi)放地址法、再哈希法、鏈地址法和建立一個(gè)公共溢出區(qū)。

             

            clip_image002

            圖4 Hash加密過(guò)程(圖片來(lái)源wiki)

             

                   現(xiàn)在讓我們來(lái)實(shí)現(xiàn)通用的hash加密方法。

             

            /// <summary>
            /// Encrypts the specified hash algorithm.
            /// 1. Generates a cryptographic Hash Key for the provided text data.
            /// </summary>
            /// <param name="hashAlgorithm">The hash algorithm.</param>
            /// <param name="dataToHash">The data to hash.</param>
            /// <returns></returns>
            public static string Encrypt(HashAlgorithm hashAlgorithm, string dataToHash)
            {
            var tabStringHex = new string[16];
            var UTF8 = new System.Text.UTF8Encoding();
            byte[] data = UTF8.GetBytes(dataToHash);
            byte[] result = hashAlgorithm.ComputeHash(data);
            var hexResult = new StringBuilder(result.Length);
            for (int i = 0; i < result.Length; i++)
            {
            //// Convert to hexadecimal
            hexResult.Append(result[i].ToString("X2"));
            }
            return hexResult.ToString();
            }

             

                   上面的加密方法包含一個(gè)HashAlgorithm類型的參數(shù),我們可以傳遞繼承于抽象類HashAlgorithm的具體hash算法(MD5,SHA1和SHA256等),通過(guò)繼承多態(tài)性我們使得加密方法更加靈活、簡(jiǎn)單,最重要的是現(xiàn)在我們只需維護(hù)一個(gè)通用的加密方法就OK了。

                   接著我們要添加判斷加密后哈希值是否相等的方法,判斷哈希值是否相等的方法IsHashMatch()方法。

             

            /// <summary>
            /// Determines whether [is hash match] [the specified hash algorithm].
            /// </summary>
            /// <param name="hashAlgorithm">The hash algorithm.</param>
            /// <param name="hashedText">The hashed text.</param>
            /// <param name="unhashedText">The unhashed text.</param>
            /// <returns>
            /// <c>true</c> if [is hash match] [the specified hash algorithm];
            /// otherwise, <c>false</c>.
            /// </returns>
            public static bool IsHashMatch(HashAlgorithm hashAlgorithm,
            string hashedText, string unhashedText)
            {
            string hashedTextToCompare = Encrypt(
            hashAlgorithm, unhashedText);
            return (String.Compare(hashedText,
            hashedTextToCompare, false) == 0);
            }

            對(duì)稱加密算法

                   現(xiàn)在我們完成了通用的Hash加密方法了,接下來(lái)我們繼續(xù)介紹對(duì)稱和非對(duì)稱算法(具體Demo可以參考這里)。

                   在實(shí)現(xiàn)對(duì)稱加密算法之前,先讓我們了解一下對(duì)稱加密的過(guò)程,假設(shè)我們有一組數(shù)據(jù)要加密那么我們可以使用一個(gè)或一組密鑰對(duì)數(shù)據(jù)進(jìn)行加密解密,但存在一個(gè)問(wèn)題對(duì)稱加密算法的密鑰長(zhǎng)度不盡相同,如DES的密鑰長(zhǎng)度為64 bit,而AES的長(zhǎng)度可以為128bit、192bit或256 bit,難道要我們hard code每種算法的密鑰長(zhǎng)度嗎?能不能動(dòng)態(tài)地產(chǎn)生對(duì)應(yīng)算法的密鑰呢?

                   其實(shí).NET已經(jīng)提供我們根據(jù)不同的對(duì)稱算法生成對(duì)應(yīng)密鑰的方法了,并且把這些方法都封裝在PasswordDeriveBytes和Rfc2898DeriveBytes類中。

                   首先讓我們看一下PasswordDeriveBytes類包含兩個(gè)方法CryptDeriveKey和GetBytes用來(lái)產(chǎn)生對(duì)應(yīng)算法的密鑰,現(xiàn)在讓我們看一下它們?nèi)绾萎a(chǎn)生密鑰。

             

            CryptDeriveKey:

             

            // The sample function.
            public void Encrypt()
            {
            // The size of the IV property must be the same as the BlockSize property.
            // Due to the RC2 block size is 64 bytes, so iv size also is 64 bytes.
            var iv = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            var pdb = new PasswordDeriveBytes("pwd", null);
            // Set the encrypted algorithm and export key algorithm.
            // Then get the key base on encrypt algorithm.
            byte[] key = pdb.CryptDeriveKey("RC2", "SHA1", 128, iv);
            Console.WriteLine(key.Length * 8);
            Console.WriteLine(new RC2CryptoServiceProvider().BlockSize);
            // Creates an RC2 object to encrypt with the derived key
            var rc2 = new RC2CryptoServiceProvider
            {
            Key = key,
            IV = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28 }
            };
            // now encrypt with it
            byte[] plaintext = Encoding.UTF8.GetBytes("NeedToEncryptData");
            using (var ms = new MemoryStream())
            {
            var cs = new CryptoStream(
            ms, rc2.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(plaintext, 0, plaintext.Length);
            cs.Close();
            byte[] encrypted = ms.ToArray();
            }
            }

                   示意例子一:我們使用SHA1哈希算法為RC2加密算法生成128bit的密鑰,這樣我們就可以根據(jù)不同對(duì)稱加密算法獲取相應(yīng)長(zhǎng)度的密鑰了,注意我們并沒(méi)用動(dòng)態(tài)地生成初始化向量iv,這是為了簡(jiǎn)單起見(jiàn)實(shí)際中不應(yīng)該這樣獲取初始化向量。

                    接下來(lái)讓我們看一下通過(guò)PBKDF1和PBKDF2s算法生成密鑰的實(shí)現(xiàn)。

             

            PBKDF1

                    GetBytes:PasswordDeriveBytes的GetBytes()方法實(shí)現(xiàn)了PBKDF1(Password Based Key Derivation Function)。

             

            PBKDF1算法過(guò)程:

            1.拼接密鑰和鹽:R0 = Pwd + Salt

            2.哈希加密過(guò)程:R1 = Hash(R2-1)

            ……..

            3.哈希加密過(guò)程:Rn = Hash(Rn - 1)

            4.n是迭代的次數(shù)(參考PBKDF1規(guī)范請(qǐng)點(diǎn)這里)

             

                  現(xiàn)在我們對(duì)PBKDF1算法的原理有了初步的了解,接下來(lái)我們將通過(guò)GetBytes()調(diào)用該算法生成密鑰。

             

            /// <summary>
            /// Uses the PBKDF1 to genernate key,
            /// then use it to encrypt plain text.
            /// </summary>
            public void PBKDF1()
            {
            byte[] salt = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            // Creates an RC2 object to encrypt with the derived key
            var pdb = new PasswordDeriveBytes("pwd", salt)
            {IterationCount = 23, HashName = "SHA1"};
            // Gets the key and iv.
            byte[] key = pdb.GetBytes(16);
            byte[] iv = pdb.GetBytes(8);
            var rc2 = new RC2CryptoServiceProvider { Key = key, IV = iv };
            byte[] plaintext = Encoding.UTF8.GetBytes("NeedToEncryptData");
            using (var ms = new MemoryStream())
            {
            // Encrypts data.
            var cs = new CryptoStream(
            ms, rc2.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(plaintext, 0, plaintext.Length);
            cs.Close();
            byte[] encrypted = ms.ToArray();
            }
            }

             

                   示意例子二:我們使用PBKDF1算法為RC2加密算法生成128 bit的密鑰和64 bit的初始化向量,要注意的是PasswordDeriveBytes的GetBytes()方法已經(jīng)過(guò)時(shí)了,而它的替代項(xiàng)就是接下來(lái)要介紹的Rfc2898DeriveBytes的GetBytes()方法。

             

            PBKDF2

                   GetBytes:由于Rfc2898DeriveBytes的GetBytes()方法實(shí)現(xiàn)了PBKDF2算法,而且它也替代了PBKDF1過(guò)時(shí)的GetBytes()方法,所以我們推薦使用Rfc2898DeriveBytes的GetBytes()方法。

             

            /// <summary>
            /// Uses the PBKDF2 to genernate key,
            /// then use it to encrypt plain text.
            /// </summary>
            public void PBKDF2()
            {
            byte[] salt = new byte[] { 23, 21, 32, 33, 46, 59, 60, 74 };
            var rfc = new Rfc2898DeriveBytes("pwd", salt, 23);
            // generate key and iv.
            byte[] key = rfc.GetBytes(16);
            byte[] iv = rfc.GetBytes(8);
            // Creates an RC2 object to encrypt with the derived key
            var rc2 = new RC2CryptoServiceProvider { Key = key, IV = iv };
            // Encrypts the data.
            byte[] plaintext = Encoding.UTF8.GetBytes("NeedToEncryptData");
            using (var ms = new MemoryStream())
            {
            var cs = new CryptoStream(
            ms, rc2.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(plaintext, 0, plaintext.Length);
            cs.Close();
            byte[] encrypted = ms.ToArray();
            }
            }

             

                   示意例子三:我們發(fā)現(xiàn)PBKDF2()方法和之前的PBKDF1()方法沒(méi)有什么區(qū)別,就是無(wú)需指定加密密鑰的哈希算法(參考PBKDF2規(guī)范請(qǐng)點(diǎn)這里)。

                  前面通過(guò)三種方法來(lái)動(dòng)態(tài)的生成加密密鑰,而且我們將使用Rfc2898DeriveBytes的GetBytes()方法來(lái)獲取密鑰,那么接下來(lái)讓我們使用該方法實(shí)現(xiàn)通用的對(duì)稱加密算法吧!

             encrypts4

            圖5 對(duì)稱算法加密過(guò)程

             

                  首先我們對(duì)加密的平文進(jìn)行編碼,這里默認(rèn)使用UTF8對(duì)平文進(jìn)行編碼,也可以使用其他編碼方式,接著使用相應(yīng)加密算法對(duì)編碼后的平文進(jìn)行加密,最后把加密后的Byte數(shù)組轉(zhuǎn)換為Base64格式字符串返回。

             

            /// <summary>
            /// Encrypts with specified symmetric algorithm.
            /// Can be Aes, DES, RC2, Rijndael and TripleDES.
            /// </summary>
            /// <param name="algorithm">The symmertric algorithm (Aes, DES, RC2, Rijndael and TripleDES).</param>
            /// <param name="plainText">The plain text need to be encrypted.</param>
            /// <param name="key">The secret key to encrypt plain text.</param>
            /// <param name="iv">The iv should be 16 bytes.</param>
            /// <param name="salt">Salt to encrypt with.</param>
            /// <param name="pwdIterations">The number of iterations for plain text.</param>
            /// <param name="keySize">Size of the key.</param>
            /// <param name="cipherMode">The cipher mode.</param>
            /// <param name="paddingMode">The padding mode.</param>
            /// <returns></returns>
            public static byte[] Encrypt(SymmetricAlgorithm algorithm, byte[] plainText, string key, string iv,
            string salt, int pwdIterations, int keySize, CipherMode cipherMode, PaddingMode paddingMode)
            {
            if (null == plainText)
            throw new ArgumentNullException("plainText");
            if (null == algorithm)
            throw new ArgumentNullException("algorithm");
            if (String.IsNullOrEmpty(key))
            throw new ArgumentNullException("key");
            if (String.IsNullOrEmpty(iv))
            throw new ArgumentNullException("iv");
            if (String.IsNullOrEmpty(salt))
            throw new ArgumentNullException("salt");
            // Note the salt should be equal or greater that 64bit (8 byte).
            var rfc = new Rfc2898DeriveBytes(key, salt.ToByteArray(), pwdIterations);
            using (SymmetricAlgorithm symmAlgo = algorithm)
            {
            symmAlgo.Mode = cipherMode;
            //symmAlgo.Padding = paddingMode;
            byte[] cipherTextBytes = null;
            using (var encryptor = symmAlgo.CreateEncryptor(
            rfc.GetBytes(keySize / 8), iv.ToByteArray()))
            {
            using (var ms = new MemoryStream())
            {
            using (var cs = new CryptoStream(
            ms, encryptor, CryptoStreamMode.Write))
            {
            cs.Write(plainText, 0, plainText.Length);
            cs.FlushFinalBlock();
            cipherTextBytes = ms.ToArray();
            ms.Close();
            cs.Close();
            }
            }
            symmAlgo.Clear();
            return cipherTextBytes;
            }
            }
            }

             

            encrypts5

            圖5 對(duì)稱算法解密過(guò)程

             

                    通過(guò)上圖的解密過(guò)程,我們發(fā)現(xiàn)解密過(guò)程恰恰是加密的反向,首先把Base64格式的密文轉(zhuǎn)換為Byte數(shù)組,接著使用對(duì)應(yīng)的解密算法解密密文,最后對(duì)解密后的數(shù)據(jù)進(jìn)行編碼返回平文(默認(rèn)使用UTF8)。

             

            /// <summary>
            /// Decrypts the specified algorithm.
            /// Can be Aes, DES, RC2, Rijndael and TripleDES.
            /// </summary>
            /// <param name="algorithm">The symmertric algorithm (Aes, DES, RC2, Rijndael and TripleDES).</param>
            /// <param name="cipherText">The cipher text.</param>
            /// <param name="key">The secret key to decrypt plain text.</param>
            /// <param name="iv">The iv should be 16 bytes.</param>
            /// <param name="salt">Salt to decrypt with.</param>
            /// <param name="pwdIterations">The number of iterations for plain text.</param>
            /// <param name="keySize">Size of the key.</param>
            /// <param name="cipherMode">The cipher mode.</param>
            /// <param name="paddingMode">The padding mode.</param>
            /// <returns></returns>
            public static byte[] Decrypt(SymmetricAlgorithm algorithm, byte[] cipherText,
            string key, string iv, string salt, int pwdIterations, int keySize,
            CipherMode cipherMode, PaddingMode paddingMode)
            {
            if (null == cipherText)
            throw new ArgumentNullException("cipherText");
            if (null == algorithm)
            throw new ArgumentNullException("algorithm");
            if (String.IsNullOrEmpty(key))
            throw new ArgumentNullException("key");
            if (String.IsNullOrEmpty(iv))
            throw new ArgumentNullException("iv");
            if (String.IsNullOrEmpty(salt))
            throw new ArgumentNullException("salt");
            // Note the salt should be equal or greater that 64bit (8 byte).
            var rfc = new Rfc2898DeriveBytes(key, salt.ToByteArray(), pwdIterations);
            using (SymmetricAlgorithm symmAlgo = algorithm)
            {
            symmAlgo.Mode = cipherMode;
            //symmAlgo.Padding = paddingMode;
            byte[] plainTextBytes = new byte[cipherText.Length];
            int cnt = -1;
            using (var encryptor = symmAlgo.CreateDecryptor(
            rfc.GetBytes(keySize / 8), iv.ToByteArray()))
            {
            using (var ms = new MemoryStream(cipherText))
            {
            using (var cs = new CryptoStream(
            ms, encryptor, CryptoStreamMode.Read))
            {
            cnt = cs.Read(plainTextBytes, 0, plainTextBytes.Length);
            ms.Close();
            cs.Close();
            }
            }
            }
            symmAlgo.Clear();
            Array.Resize(ref plainTextBytes, cnt);
            return plainTextBytes;
            }
            }

                  在前面的加密和解密方法,我們通過(guò)Rfc2898DeriveBytes獲取密碼、salt 值和迭代次數(shù),然后通過(guò)調(diào)用GetBytes方法生成密鑰。

                   現(xiàn)在我們已經(jīng)完成了通用的對(duì)稱加密算法,我們只需一組加密和解密方法就可以隨意的使用任意一種對(duì)稱加密算法了,而不是為每個(gè)加密和解密算法編寫(xiě)相應(yīng)的加密和解密方法。

             

            非對(duì)稱加密算法

                  .NET Framework中提供四種非對(duì)稱加密算法(DSAECDiffieHellman, ECDsaRSA),它們都繼承于抽象類AsymmetricAlgorithm,接下來(lái)我們將提供RSA算法的實(shí)現(xiàn)。

                  RSA加密算法是一種非對(duì)稱和雙鑰加密算法,在公鑰加密標(biāo)準(zhǔn)和電子商業(yè)中RSA被廣泛使用。

                  在雙鑰加密的情況下,密鑰有兩把,一把是公開(kāi)的公鑰,還有一把是不公開(kāi)的私鑰。

             

            雙鑰加密的原理如下:

            a) 公鑰和私鑰是一一對(duì)應(yīng)的關(guān)系,有一把公鑰就必然有一把與之對(duì)應(yīng)的、獨(dú)一無(wú)二的私鑰,反之亦成立。

            b) 所有的(公鑰, 私鑰)對(duì)都是不同的。

            c) 用公鑰可以解開(kāi)私鑰加密的信息,反之亦成立。

            d) 同時(shí)生成公鑰和私鑰應(yīng)該相對(duì)比較容易,但是從公鑰推算出私鑰,應(yīng)該是很困難或者是不可能的。

             

                   現(xiàn)在的數(shù)字簽名加密主要是使用RSA算法,什么是數(shù)字簽名大家請(qǐng)點(diǎn)這里(中文)和這里(英文)。

                   現(xiàn)在我們知道RSA算法是使用公鑰和密鑰進(jìn)行加密和解密,所以我們先定義一個(gè)方法來(lái)生成公鑰和密鑰。

             

            /// <summary>
            /// Generates the RSA public and private key.
            /// </summary>
            /// <param name="algorithm">The algorithm to creates key.</param>
            /// <returns></returns>
            public static void GenerateRSAKey(RSACryptoServiceProvider algorithm)
            {
            // Contains public and private key.
            RSAPrivateKey = algorithm.ToXmlString(true);
            using (var streamWriter = new StreamWriter("PublicPrivateKey.xml"))
            {
            streamWriter.Write(RSAPrivateKey);
            }
            // Only contains public key.
            RSAPubicKey = algorithm.ToXmlString(false);
            using (var streamWriter = new StreamWriter("PublicOnlyKey.xml"))
            {
            streamWriter.Write(RSAPubicKey);
            }
            }

             

                   通過(guò)RSACryptoServiceProvider的ToXmlString()方法我們生成了一對(duì)公鑰和密鑰,當(dāng)參數(shù)為true 表示同時(shí)包含 RSA 公鑰和私鑰,反之表示僅包含公鑰。

             

            /// <summary>
            /// Encrypts with the specified RSA algorithm.
            /// </summary>
            /// <param name="rsa">A RSA object.</param>
            /// <param name="plainText">The plain text to decrypt.</param>
            /// <param name="key">The key.</param>
            /// <param name="encoding">The encoding.</param>
            /// <returns></returns>
            public static string Encrypt(RSACryptoServiceProvider rsa,
            string plainText, string key, Encoding encoding)
            {
            if (null == rsa)
            throw new ArgumentNullException("rsa");
            if (String.IsNullOrEmpty(plainText))
            throw new ArgumentNullException("plainText");
            if (String.IsNullOrEmpty(key))
            throw new ArgumentNullException("key");
            if (null == encoding)
            throw new ArgumentNullException("encoding");
            string publicKey;
            // Reads public key.
            using (var streamReader = new StreamReader("PublicOnlyKey.xml"))
            {
            publicKey = streamReader.ReadToEnd();
            }
            rsa.FromXmlString(publicKey);
            byte[] cipherBytes = rsa.Encrypt(plainText.ToBytesEncoding(encoding), true);
            rsa.Clear();
            return cipherBytes.ToBase64String();
            }

             

                   接著我們定義RSA的加密方法,首先我們從流中讀取密鑰和公鑰,然后傳遞給FromXmlString()方法,最后對(duì)平文進(jìn)行加密。

             

            /// <summary>
            /// Decrypts with the specified RSA algorithm.
            /// </summary>
            /// <param name="rsa">a RSA object.</param>
            /// <param name="cipherText">The cipher text to encrypt.</param>
            /// <param name="key">The key.</param>
            /// <param name="encoding">The encoding.</param>
            /// <returns></returns>
            public static string Decrypt(RSACryptoServiceProvider rsa,
            string cipherText, string key, Encoding encoding)
            {
            string privateKey;
            // Reads the private key.
            using (var streamReader = new StreamReader("PublicPrivateKey.xml"))
            {
            privateKey = streamReader.ReadToEnd();
            }
            rsa.FromXmlString(privateKey);
            byte[] plainBytes = rsa.Decrypt(cipherText.FromBase64String(), true);
            rsa.Clear();
            return plainBytes.FromByteToString(encoding);
            }

             

                   參照加密方法我們很快的實(shí)現(xiàn)RSA的解密方法,同樣我們從流中讀取密鑰,然后傳遞給FromXmlString()方法,最后對(duì)密文進(jìn)行解密,注意調(diào)用的是RSA算法的Decrypt()方法,在使用膠水代碼時(shí)千萬(wàn)別忘記修改了。

                   現(xiàn)在我們終于完成了通用的加密解密方法,接下來(lái)肯定是要測(cè)試一下這些方法的效果如何,這次我使用單元測(cè)試,如果大家要參考應(yīng)用程序效果可以點(diǎn)這里。

             

            [TestMethod]
            public void TestStart()
            {
            try
            {
            string cipherText;
            string plainText;
            #region Hash Algo
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateHashAlgoMd5(), @"您們好(Hello everyone).");
            Assert.IsTrue(CryptographyUtils.IsHashMatch(
            CryptographyUtils.CreateHashAlgoMd5(),
            cipherText, @"您們好(Hello everyone)."));
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateHashAlgoSHA1(),
            @"您們好(Hello everyone).");
            Assert.IsTrue(CryptographyUtils.IsHashMatch(
            CryptographyUtils.CreateHashAlgoSHA1(),
            cipherText, @"您們好(Hello everyone)."));
            #endregion
            #region Asymm Algo
            CryptographyUtils.GenerateRSAKey(CryptographyUtils.CreateAsymmAlgoRSA());
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateAsymmAlgoRSA(), @"%dk>JK.RusH", @"c579D-E>?$)_");
            plainText = CryptographyUtils.Decrypt(
            CryptographyUtils.CreateAsymmAlgoRSA(), cipherText, @"c579D-E>?$)_");
            Assert.AreEqual<string>(@"%dk>JK.RusH", plainText);
            #endregion
            #region Symm Algo
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateSymmAlgoAes(),
            "JK_huangJK_huangJK_huang黃鈞航",
            "JK_huangJK_huang", 256);
            plainText = CryptographyUtils.Decrypt(
            CryptographyUtils.CreateSymmAlgoAes(),
            cipherText, "JK_huangJK_huang", 256);
            Assert.AreEqual<string>("JK_huangJK_huangJK_huang黃鈞航",
            plainText);
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateSymmAlgoDES(),
            "JK_huangJK_huangJK_huang黃鈞航",
            "JK_huangJK_huang", 64);
            plainText = CryptographyUtils.Decrypt(
            CryptographyUtils.CreateSymmAlgoDES(),
            cipherText, "JK_huangJK_huang", 64);
            Assert.AreEqual<string>("JK_huangJK_huangJK_huang黃鈞航",
            plainText);
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateSymmAlgoRC2(),
            "JK_huangJK_huangJK_huang黃鈞航",
            "JK_huangJK_huang", 128);
            plainText = CryptographyUtils.Decrypt(CryptographyUtils.CreateSymmAlgoRC2(),
            cipherText, "JK_huangJK_huang", 128);
            Assert.AreEqual<string>("JK_huangJK_huangJK_huang黃鈞航", plainText);
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateSymmAlgoRijndael(),
            "JK_huangJK_huangJK_huang黃鈞航",
            "JK_huangJK_huang", 256);
            plainText = CryptographyUtils.Decrypt(
            CryptographyUtils.CreateSymmAlgoRijndael(),
            cipherText, "JK_huangJK_huang", 256);
            Assert.AreEqual<string>("JK_huangJK_huangJK_huang黃鈞航", plainText);
            cipherText = CryptographyUtils.Encrypt(
            CryptographyUtils.CreateSymmAlgoTripleDes(),
            "JK_huangJK_huangJK_huang黃鈞航",
            "JK_huangJK_huang", 192);
            plainText = CryptographyUtils.Decrypt(
            CryptographyUtils.CreateSymmAlgoTripleDes(),
            cipherText, "JK_huangJK_huang", 192);
            Assert.AreEqual<string>("JK_huangJK_huangJK_huang黃鈞航", plainText);
            #endregion
            }
            catch (Exception ex)
            {
            Debug.Assert(false, ex.Message);
            }
            }

             

            encrypt8

            圖6 單元測(cè)試結(jié)果

             

            1.1.3 總結(jié)

                   本文給出了.NET中的一些加密算法的通用實(shí)現(xiàn)(哈希加密,對(duì)稱加密和非對(duì)稱加密算法),由于加密和解密的方法都是比較固定,而且每中算法有具有其特性,所以這里我們給出了它們的實(shí)現(xiàn),而且我們可以把上的方法封裝在一個(gè)加密Helper類,這樣可以大大提高我們開(kāi)發(fā)效率,而且它充分的利用多態(tài)性使得加密算法靈活性和維護(hù)性大大提高。

            Logo
            作者:Gezidan
            出處:http://www.rixu.net    
            本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
            posted on 2011-09-26 09:48 日需博客 閱讀(1068) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C# 、技術(shù)文章 、轉(zhuǎn)載
            久久久久一区二区三区| 亚洲中文字幕无码久久综合网| 国产成人精品综合久久久久| 久久久久人妻一区精品 | 久久精品人妻中文系列| 日日狠狠久久偷偷色综合免费| 国产高清美女一级a毛片久久w| 狠狠色丁香婷婷久久综合不卡| 精品久久一区二区三区| 久久99精品国产一区二区三区| 97精品久久天干天天天按摩| 久久精品国产第一区二区三区| 亚洲精品乱码久久久久久蜜桃图片| 亚洲精品WWW久久久久久| 色婷婷久久久SWAG精品| 久久久国产视频| 亚洲精品tv久久久久久久久| 久久久久人妻一区精品色| 国产午夜福利精品久久2021| 99久久99久久精品免费看蜜桃| 久久综合久久综合久久| 成人a毛片久久免费播放| 久久影视国产亚洲| 久久久久久免费一区二区三区| 国产三级久久久精品麻豆三级| 久久这里只有精品视频99| 久久亚洲国产成人精品无码区| 久久毛片免费看一区二区三区| 久久中文字幕精品| 熟妇人妻久久中文字幕| 国内精品久久久久久99蜜桃| 99精品伊人久久久大香线蕉| 香蕉99久久国产综合精品宅男自 | 少妇高潮惨叫久久久久久| 久久久久久久亚洲Av无码| 久久免费小视频| 一级女性全黄久久生活片免费| 久久国产精品99精品国产| 精品久久久无码中文字幕| 亚洲中文久久精品无码| 国产69精品久久久久99尤物|