程序員之網絡安全系列(三):數據加密之對稱加密算法

系列目錄:html

前文回顧

假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去程序員

  1. 如何保證隔壁老王不能看到情書內容?(保密性)
  2. 如何保證隔壁老王不修改情書的內容?(完整性)
  3. 如何保證隔壁老王不冒充明明?(身份認證)
  4. 如何保證實明不可否認情書是本身寫的?(來源的不能否認)

上一節,咱們使用了Hash算法保證了情書的完整性,也就是確保「隔壁王叔叔」沒有修改明明的情書,那麼這一節咱們來看看如何保證「隔壁王叔叔」不能看到情書的內容,也就是保密性。算法

數據加密

要想不讓別人看到數據,那麼咱們就們就須要對數據加密。安全

加密技術 是最經常使用的安全保密手段,利用技術手段把重要的數據變爲亂碼(加密)傳送,到達目的地後再用相同或不一樣的手段還原(解密)。
加密包括兩個元素:算法和密鑰。一個加密算法是將普通的文本(或者能夠理解的信息)與一竄數字(密鑰)的結合,產生不可理解的密文的步驟,密鑰是用來對數據進行編碼和解碼的一種算法。網絡

舉個例子:編碼

假設咱們要對LOVE加密,咱們能夠先定義字母的順序ABCDEFGHIJKLMNOPQRSTUVWXYZ,而後咱們讓每一個字母向後移動兩位,那麼LOVE就變爲了NQXG加密

L------>N
O------>Q
V------>X
E------>
LOVE--->NQXG

我想這就是最簡單的加密方式。spa

密鑰加密技術的密碼體制分爲對稱密鑰體制和非對稱密鑰體制兩種。code

對數據加密的技術分爲兩類,即對稱加密(私人密鑰加密)和非對稱加密(公開密鑰加密)。對稱加密以數據加密標準(DES,Data Encryption Standard)算法爲典型表明,非對稱加密一般以RSA(Rivest Shamir Ad1eman)算法爲表明。對稱加密的加密密鑰和解密密鑰相同,而非對稱加密的加密密鑰和解密密鑰不一樣,加密密鑰能夠公開而解密密鑰須要保密。htm

對稱加密

對稱加密採用了對稱密碼編碼技術,它的特色是文件加密和解密使用相同的密鑰,即加密密鑰也能夠用做解密密鑰。
好比,咱們給WORD文檔設置密碼1234, 那麼其餘人想要打開文檔也必須輸入1234才能打開。

經常使用加密算法:

  • DES(Data Encryption Standard):數據加密標準,速度較快,適用於加密大量數據的場合。
  • 3DES(Triple DES):是基於DES,對一塊數據用三個不一樣的密鑰進行三次加密,強度更高。
  • AES(Advanced Encryption Standard):高級加密標準,是下一代的加密算法標準,速度快,安全級別高;
  • RC4,也是爲 RSA Data Security, Inc. 開發的密碼系統的商標名稱。

傳統的DES因爲只有56位的密鑰,從1997年開始,RSA公司發起了一個稱做「向DES挑戰」的競技賽。在首屆挑戰賽上,羅克·維瑟用了96天時間破解了用DES加密的一段信息。1999年12月22日,RSA公司發起「第三屆DES挑戰賽(DES Challenge III)」。2000年1月19日,由電子邊疆基金會組織研製的25萬美圓的DES解密機以22.5小時的戰績,成功地破解了 DES加密算法。DES已逐漸完成了它的歷史使命。

高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。通過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPS PUB 197,並在2002年5月26日成爲有效的標準。2006年,高級加密標準已然成爲對稱密鑰加密中最流行的算法之一。

對稱加密算法的優勢:

  • 算法公開
  • 計算量小
  • 加密速度快,加密效率高

對稱加密算法的缺點

  • 加解密雙方須要使用相同的祕鑰
  • 祕鑰管理很不方便,若是用戶不少,那麼祕鑰的管理成幾何性增加
  • 任何一方祕鑰泄露,數據都不安全了

最後

經過本節,咱們知道當明明給麗麗情書時,能夠用DES或者AES對數據進行加密,即便「隔壁王叔叔」拿到信件也看不懂內容,同時使用上一節的Hash算法保證了情書的內容完整,可是這就須要明明和麗麗提早設置一個祕鑰。

代碼示例

下面的代碼輸出以下結果

I Love You, Li Li
    Encrypeted: 0t9glwGMmwtGs8B4QCotyZkKf091WElCwG659QiVVw0=
    Decrypeted: I Love You, Li Li

.NET 源碼:

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

    namespace AES
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                string password = "Don't believe wang shu shu";
                string orginTextToSent = "I Love You, Li Li";
                Console.WriteLine (orginTextToSent);

                string encryptedText=EncryptText(orginTextToSent, password);

                Console.WriteLine ("Encrypeted: " + encryptedText);

                string DecryptedText = DecryptText (encryptedText, password);
                Console.WriteLine ("Decrypeted: " + DecryptedText);

            }



            public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
            {
                byte[] encryptedBytes = null;

                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;

                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);

                        AES.Mode = CipherMode.CBC;

                        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                            cs.Close();
                        }
                        encryptedBytes = ms.ToArray();
                    }
                }

                return encryptedBytes;
            }

            public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
            {
                byte[] decryptedBytes = null;

                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;

                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);

                        AES.Mode = CipherMode.CBC;

                        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                            cs.Close();
                        }
                        decryptedBytes = ms.ToArray();
                    }
                }

                return decryptedBytes;
            }


            public static string EncryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

                string result = Convert.ToBase64String(bytesEncrypted);

                return result;
            }

            public static string DecryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

                string result = Encoding.UTF8.GetString(bytesDecrypted);

                return result;
            }

        }
    }
相關文章
相關標籤/搜索