日韩亚洲欧美在线com|日本xxxx色视频在线播放|国产熟妇与子伦hd|欧美freesex黑人又粗又大|国产欧美日韩一区二区三区

0、摘要

      今天看到吉日嘎拉一篇關(guān)于管理軟件中信息加密和安全的文章,感覺非常有實(shí)際意義。文中作者從實(shí)踐經(jīng)驗(yàn)出發(fā),討論了信息管理軟件中如何通過哈希和加密進(jìn)行數(shù)據(jù)保護(hù)。但是從文章評(píng)論中也可以看出很多朋友對(duì)這個(gè)方面一些基本概念比較模糊,這樣就容易“照葫蘆畫瓢”,不能根據(jù)自身具體情況靈活選擇和使用各種哈希和加密方式。本文不對(duì)哈希和加密做過于深入的討論,而是對(duì)哈希和加密的基本概念和原理進(jìn)行闡述、比較,并結(jié)合具體實(shí)踐說明如何選擇哈希和加密算法、如何提高安全性等問題,使朋友們做到“知其然,知其所以然”,這樣就能通過分析具體情況,靈活運(yùn)用哈希和加密保護(hù)數(shù)據(jù)。

1、哈希(Hash)與加密(Encrypt)的區(qū)別

      在本文開始,我需要首先從直觀層面闡述哈希(Hash)加密(Encrypt)的區(qū)別,因?yàn)槲乙娺^很多朋友對(duì)這兩個(gè)概念不是很清晰,容易混淆兩者。而正確區(qū)別兩者是正確選擇和使用哈希與加密的基礎(chǔ)。

      概括來說,哈希(Hash)是將目標(biāo)文本轉(zhuǎn)換成具有相同長度的、不可逆的雜湊字符串(或叫做消息摘要),而加密(Encrypt)是將目標(biāo)文本轉(zhuǎn)換成具有不同長度的、可逆的密文。

      具體來說,兩者有如下重要區(qū)別:

      1、哈希算法往往被設(shè)計(jì)成生成具有相同長度的文本,而加密算法生成的文本長度與明文本身的長度有關(guān)。

      例如,設(shè)我們有兩段文本:“Microsoft”和“Google”。兩者使用某種哈希算法得到的結(jié)果分別為:“140864078AECA1C7C35B4BEB33C53C34”和“8B36E9207C24C76E6719268E49201D94”,而使用某種加密算法的到的結(jié)果分別為“Njdsptpgu”和“Hpphmf”。可以看到,哈希的結(jié)果具有相同的長度,而加密的結(jié)果則長度不同。實(shí)際上,如果使用相同的哈希算法,不論你的輸入有多么長,得到的結(jié)果長度是一個(gè)常數(shù),而加密算法往往與明文的長度成正比。

      2、哈希算法是不可逆的,而加密算法是可逆的。

      這里的不可逆有兩層含義,一是“給定一個(gè)哈希結(jié)果R,沒有方法將E轉(zhuǎn)換成原目標(biāo)文本S”,二是“給定哈希結(jié)果R,即使知道一段文本S的哈希結(jié)果為R,也不能斷言當(dāng)初的目標(biāo)文本就是S”。其實(shí)稍微想想就知道,哈希是不可能可逆的,因?yàn)槿绻赡妫敲垂>褪鞘澜缟献顝?qiáng)悍的壓縮方式了——能將任意大小的文件壓縮成固定大小。

      加密則不同,給定加密后的密文R,存在一種方法可以將R確定的轉(zhuǎn)換為加密前的明文S。

      這里先從直觀層面簡單介紹兩者的區(qū)別,等下文從數(shù)學(xué)角度對(duì)兩者做嚴(yán)謹(jǐn)描述后,讀者朋友就知道為什么會(huì)有這兩個(gè)區(qū)別了。

2、哈希(Hash)與加密(Encrypt)的數(shù)學(xué)基礎(chǔ)

      從數(shù)學(xué)角度講,哈希和加密都是一個(gè)映射。下面正式定義兩者:

      一個(gè)哈希算法是一個(gè)多對(duì)一映射,給定目標(biāo)文本S,H可以將其唯一映射為R,并且對(duì)于所有S,R具有相同的長度。由于是多對(duì)一映射,所以H不存在逆映射

使得R轉(zhuǎn)換為唯一的S。

      一個(gè)加密算法是一個(gè)一一映射,其中第二個(gè)參數(shù)叫做加密密鑰,E可以將給定的明文S結(jié)合加密密鑰Ke唯一映射為密文R,并且存在另一個(gè)一一映射,可以結(jié)合Kd將密文R唯一映射為對(duì)應(yīng)明文S,其中Kd叫做解密密鑰。

      下圖是哈希和加密過程的圖示:

      有了以上定義,就很清楚為什么會(huì)存在上文提到的兩個(gè)區(qū)別了。由于哈希算法的定義域是一個(gè)無限集合,而值域是一個(gè)有限集合,將無限集合映射到有限集合,根據(jù)“鴿籠原理(Pigeonhole principle)”,每個(gè)哈希結(jié)果都存在無數(shù)個(gè)可能的目標(biāo)文本,因此哈希不是一一映射,是不可逆的。

      而加密算法是一一映射,因此理論上來說是可逆的。

      但是,符合上面兩個(gè)定義的映射僅僅可以被叫做哈希算法和加密算法,但未必是好的哈希和加密,好的哈希和加密往往需要一些附加條件,下面介紹這些內(nèi)容。

      一個(gè)設(shè)計(jì)良好的哈希算法應(yīng)該很難從哈希結(jié)果找到哈希目標(biāo)文本的碰撞(Collision)。那么什么是碰撞呢?對(duì)于一個(gè)哈希算法H,如果,則S1和S2互為碰撞。關(guān)于為什么好的哈希需要難以尋找碰撞,在下面講應(yīng)用的時(shí)候會(huì)詳解。另外,好的哈希算法應(yīng)該對(duì)于輸入的改變極其敏感,即使輸入有很小的改動(dòng),如一億個(gè)字符變了一個(gè)字符,那么結(jié)果應(yīng)該截然不同。這就是為什么哈希可以用來檢測軟件的完整性。

      一個(gè)設(shè)計(jì)良好的加密算法應(yīng)該是一個(gè)“單向陷門函數(shù)(Trapdoor one-way function)”,單向陷門函數(shù)的特點(diǎn)是一般情況下即使知道函數(shù)本身也很難將函數(shù)的值轉(zhuǎn)換回函數(shù)的自變量,具體到加密也就是說很難從密文得到明文,雖然從理論上這是可行的,而“陷門”是一個(gè)特殊的元素,一旦知道了陷門,則這種逆轉(zhuǎn)換則非常容易進(jìn)行,具體到加密算法,陷門就是密鑰。

      順便提一句,在加密中,應(yīng)該保密的僅僅是明文和密鑰。也就是說我們通常假設(shè)攻擊者對(duì)加密算法和密文了如指掌,因此加密的安全性應(yīng)該僅僅依賴于密鑰而不是依賴于假設(shè)攻擊者不知道加密算法。

3、哈希(Hash)與加密(Encrypt)在軟件開發(fā)中的應(yīng)用

      哈希與加密在現(xiàn)代工程領(lǐng)域應(yīng)用非常廣泛,在計(jì)算機(jī)領(lǐng)域也發(fā)揮了很大作用,這里我們僅僅討論在平常的軟件開發(fā)中最常見的應(yīng)用——數(shù)據(jù)保護(hù)。

      所謂數(shù)據(jù)保護(hù),是指在數(shù)據(jù)庫被非法訪問的情況下,保護(hù)敏感數(shù)據(jù)不被非法訪問者直接獲取。這是非常有現(xiàn)實(shí)意義的,試想一個(gè)公司的安保系統(tǒng)數(shù)據(jù)庫服務(wù)器被入侵,入侵者獲得了所有數(shù)據(jù)庫數(shù)據(jù)的查看權(quán)限,如果管理員的口令(Password)被明文保存在數(shù)據(jù)庫中,則入侵者可以進(jìn)入安保系統(tǒng),將整個(gè)公司的安保設(shè)施關(guān)閉,或者刪除安保系統(tǒng)中所有的信息,這是非常嚴(yán)重的后果。但是,如果口令經(jīng)過良好的哈希或加密,使得入侵者無法獲得口令明文,那么最多的損失只是被入侵者看到了數(shù)據(jù)庫中的數(shù)據(jù),而入侵者無法使用管理員身份進(jìn)入安保系統(tǒng)作惡。

3.1、哈希(Hash)與加密(Encrypt)的選擇

      要實(shí)現(xiàn)上述的數(shù)據(jù)保護(hù),可以選擇使用哈希或加密兩種方式。那么在什么時(shí)候該選擇哈希、什么時(shí)候該選擇加密呢?

      基本原則是:如果被保護(hù)數(shù)據(jù)僅僅用作比較驗(yàn)證,在以后不需要還原成明文形式,則使用哈希;如果被保護(hù)數(shù)據(jù)在以后需要被還原成明文,則需要使用加密。

      例如,你正在做一個(gè)系統(tǒng),你打算當(dāng)用戶忘記自己的登錄口令時(shí),重置此用戶口令為一個(gè)隨機(jī)口令,而后將此隨機(jī)口令發(fā)給用戶,讓用戶下次使用此口令登錄,則適合使用哈希。實(shí)際上很多網(wǎng)站都是這么做的,想想你以前登錄過的很多網(wǎng)站,是不是當(dāng)你忘記口令的時(shí)候,網(wǎng)站并不是將你忘記的口令發(fā)送給你,而是發(fā)送給你一個(gè)新的、隨機(jī)的口令,然后讓你用這個(gè)新口令登錄。這是因?yàn)槟阍谧?cè)時(shí)輸入的口令被哈希后存儲(chǔ)在數(shù)據(jù)庫里,而哈希算法不可逆,所以即使是網(wǎng)站管理員也不可能通過哈希結(jié)果復(fù)原你的口令,而只能重置口令。

      相反,如果你做的系統(tǒng)要求在用戶忘記口令的時(shí)候必須將原口令發(fā)送給用戶,而不是重置其口令,則必須選擇加密而不是哈希。

3.2、使用簡單的一次哈希(Hash)方法進(jìn)行數(shù)據(jù)保護(hù)

      首先我們討論使用一次哈希進(jìn)行數(shù)據(jù)保護(hù)的方法,其原理如下圖所示:

      對(duì)上圖我想已無需多言,很多朋友應(yīng)該使用過類似的哈希方法進(jìn)行數(shù)據(jù)保護(hù)。當(dāng)前最常用的哈希算法是MD5SHA1,下面給出在.NET平臺(tái)上用C#語言實(shí)現(xiàn)MD5和SHA1哈希的代碼,由于.NET對(duì)于這兩個(gè)哈希算法已經(jīng)進(jìn)行很很好的封裝,因此我們不必自己實(shí)現(xiàn)其算法細(xì)節(jié),直接調(diào)用相應(yīng)的庫函數(shù)即可(實(shí)際上MD5和SHA1算法都十分復(fù)雜,有興趣的可以參考維基百科)。

01 using System;
02 using System.Web.Security;
03   
04 namespace HashAndEncrypt
05 {
06     /// <summary>
07     /// 哈希(Hash)工具類
08     /// </summary>
09     public sealed class HashHelper
10     {
11         /// <summary>
12         /// 使用MD5算法進(jìn)行哈希
13         /// </summary>
14         /// <param name="source">源字串</param>
15         /// <returns>雜湊字串</returns>
16         public static string MD5Hash(string source)
17         {
18             return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5");
19         }
20   
21         /// <summary>
22         /// 使用SHA1算法進(jìn)行哈希
23         /// </summary>
24         /// <param name="source">源字串</param>
25         /// <returns>雜湊字串</returns>
26         public static string SHA1Hash(string source)
27         {
28             return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "SHA1");
29         }
30     }
31 }

3.3、對(duì)簡單哈希(Hash)的攻擊

      下面我們討論上述的數(shù)據(jù)保護(hù)方法是否安全。

      對(duì)于哈希的攻擊,主要有尋找碰撞法窮舉法

      先來說說尋找碰撞法。從哈希本身的定義和上面的數(shù)據(jù)保護(hù)原理圖可以看出,如果想非法登錄系統(tǒng),不一定非要得到注冊(cè)時(shí)的輸入口令,只要能得到一個(gè)注冊(cè)口令的碰撞即可。因此,如果能從雜湊串中分析出一個(gè)口令的碰撞,則大功告成。

      不過我的意見是,對(duì)這種攻擊大可不必?fù)?dān)心,因?yàn)槟壳皩?duì)于MD5和SHA1并不存在有效地尋找碰撞方法。雖然我國杰出的數(shù)學(xué)家王小云教授曾經(jīng)在國際密碼學(xué)會(huì)議上發(fā)布了對(duì)于MD5和SHA1的碰撞尋找改進(jìn)算法,但這種方法和很多人口中所說的“破解”相去甚遠(yuǎn),其理論目前僅具有數(shù)學(xué)上的意義,她將破解MD5的預(yù)期步驟數(shù)從2^80降到了2^69,雖然從數(shù)學(xué)上降低了好幾個(gè)數(shù)量級(jí),但2^69對(duì)于實(shí)際應(yīng)用來說仍然是一個(gè)天文數(shù)字,就好比以前需要一億年,現(xiàn)在需要一萬年一樣。

      不過這并不意味著使用MD5或SHA1后就萬事大吉了,因?yàn)檫有一種對(duì)于哈希的攻擊方法——窮舉法。通俗來說,就是在一個(gè)范圍內(nèi),如從000000到999999,將其中所有值一個(gè)一個(gè)用相同的哈希算法哈希,然后將結(jié)果和雜湊串比較,如果相同,則這個(gè)值就一定是源字串或源字串的一個(gè)碰撞,于是就可以用這個(gè)值非法登錄了。

      例如,下文是對(duì)MD5的窮舉攻擊的代碼(設(shè)攻擊范圍為000000到999999):

01
using System;
02 using System.Web.Security;
03   
04 namespace HashAndEncrypt
05 {
06     /// <summary>
07     /// MD5攻擊工具類
08     /// </summary>
09     public sealed class MD5AttackHelper
10     {
11         /// <summary>
12         /// 對(duì)MD5進(jìn)行窮舉攻擊
13         /// </summary>
14         /// <param name="hashString">雜湊串</param>
15         /// <returns>雜湊串的源串或源串碰撞(攻擊失敗則返回null)</returns>
16         public static string AttackMD5(string hashString)
17         {
18             for (int i = 0; i <= 999999; i++)
19             {
20                 string testString = i.ToString();
21                 while (testString.Length < 6)
22                     testString = "0" + testString;
23   
24                 if (FormsAuthentication.HashPasswordForStoringInConfigFile(testString, "MD5") == hashString)
25                     return testString;
26             }
27   
28             return null;
29         }
30     }
31 }

      這種看似笨拙的方法,在現(xiàn)實(shí)中爆發(fā)的能量卻是驚人的,目前幾乎所有的MD5破解機(jī)或MD5在線破解都是用這種窮舉法,但就是這種“笨”方法,卻成功破解出很多哈希串。糾其緣由,就是相當(dāng)一部分口令是非常簡單的,如“123456”或“000000”這種口令還有很多人在用,可以看出,窮舉法是否能成功很大程度上取決于口令的復(fù)雜性。因?yàn)楦F舉法掃描的區(qū)間往往是單字符集、規(guī)則的區(qū)間,或者由字典數(shù)據(jù)進(jìn)行組合,因此,如果使用復(fù)雜的口令,例如“ASDF#$%uiop.8930”這種變態(tài)級(jí)口令,窮舉法就很難奏效了。

3.4、對(duì)一次哈希(Hash)的改進(jìn)——多重混合哈希(Hash)

      上面說過,如果口令過于簡單,則使用窮舉法可以很有效地破解出一次哈希后的雜湊串。如果不想這樣,只有讓用戶使用復(fù)雜口令,但是,很多時(shí)候我們并不能強(qiáng)迫用戶,因此,我們需要想一種辦法,即使用戶使用諸如“000000”這種簡單密碼,也令窮舉法難奏效。其中一種辦法就是使用多重哈希,所謂多重哈希就是使用不同的哈希函數(shù)配合自定義的Key對(duì)口令進(jìn)行多次哈希,如果Key很復(fù)雜,那么窮舉法將變得異常艱難。

      例如,如果使用下面的混合公式進(jìn)行哈希:

      如果將Key設(shè)為一個(gè)極為復(fù)雜的字符串,那么在攻擊者不知道Key的情況下,幾乎無法通過窮舉法破解。因?yàn)榧词筍很簡單,但是Key的MD5值幾乎是無法在合理時(shí)間內(nèi)窮舉完的。下面是這種多重混合哈希的代碼實(shí)現(xiàn):

01 using System;
02 using System.Web.Security;
03   
04 namespace HashAndEncrypt
05 {
06     /// <summary>
07     /// 多重混合哈希工具類
08     /// </summary>
09     public sealed class HashHelper
10     {
11         private static readonly String hashKey = "qwer#&^Buaa06";
12         /// <summary>
13         /// 對(duì)敏感數(shù)據(jù)進(jìn)行多重混合哈希
14         /// </summary>
15         /// <param name="source">待處理明文</param>
16         /// <returns>Hasn后的數(shù)據(jù)</returns>
17         public static String Hash(String source)
18         {
19             String hashCode = FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5") +
20                               FormsAuthentication.HashPasswordForStoringInConfigFile(hashKey, "MD5");
21             return FormsAuthentication.HashPasswordForStoringInConfigFile(hashCode, "SHA1");
22         }
23     }
24 }

3.5、使用加密(Encrypt)方法進(jìn)行數(shù)據(jù)保護(hù)

      加密方法如果用于口令保護(hù)的話,與上述哈希方法的流程基本一致,只是在需要時(shí),可以使用解密方法得到明文。關(guān)于加密本身是一個(gè)非常龐大的系統(tǒng),而對(duì)于加密算法的攻擊更是可以寫好幾本書了,所以這里從略。下面只給出使用C#進(jìn)行DES加密和解密的代碼。

01 using System;
02 using System.Security.Cryptography;
03 using System.Text;
04 using System.Web.Security;
05   
06 namespace HashAndEncrypt
07 {
08     /// <summary>
09     /// 工具類,封裝了加解密相關(guān)操作
10     /// </summary>
11     public sealed class EncryptHelper
12     {
13         private static readonly Byte[] DesKey = {5, 7, 8, 9, 0, 2, 1, 6};
14         private static readonly Byte[] DesVi = { 6, 9, 8, 5, 1, 6, 2, 8 }; 
15         /// <summary>
16         /// 使用DES算法加密數(shù)據(jù)
17         /// </summary>
18         /// <param name="data">待加密數(shù)據(jù)</param>
19         /// <returns>密文</returns>
20         public static String Encrypt(String data)
21         {
22             DESCryptoServiceProvider des = new DESCryptoServiceProvider();
23             Encoding utf = new UTF8Encoding();
24             ICryptoTransform encryptor = des.CreateEncryptor(DesKey, DesVi);
25   
26             byte[] bData = utf.GetBytes(data);
27             byte[] bEnc = encryptor.TransformFinalBlock(bData, 0, bData.Length);
28             return Convert.ToBase64String(bEnc);
29         }
30   
31         /// <summary>
32         /// 使用DES算法解密數(shù)據(jù)
33         /// </summary>
34         /// <param name="data">待解密數(shù)據(jù)</param>
35         /// <returns>明文</returns>
36         public static String Decrypt(String data)
37         {
38             DESCryptoServiceProvider des = new DESCryptoServiceProvider();
39             Encoding utf = new UTF8Encoding();
40             ICryptoTransform decryptor = des.CreateDecryptor(DesKey, DesVi);
41   
42             byte[] bEnc = Convert.FromBase64String(data);
43             byte[] bDec = decryptor.TransformFinalBlock(bEnc, 0, bEnc.Length);
44             return utf.GetString(bDec);
45         }
46     }
47 }

4、總結(jié)

      密碼學(xué)本身是一個(gè)非常深?yuàn)W的數(shù)學(xué)分支,對(duì)于普通開發(fā)者,不需要了解過于深入的密碼學(xué)知識(shí)。本文僅僅講述哈希與加密的基礎(chǔ)內(nèi)容,并對(duì)兩者做了比較,幫助讀者明晰概念,另外,對(duì)一些實(shí)際應(yīng)用情況進(jìn)行了簡單的討論。希望本文對(duì)大家有所幫助。看了下時(shí)間,零點(diǎn)剛過,祝大家十一快樂!玩得開心!

 

Creative Commons License

本文基于署名-非商業(yè)性使用 3.0許可協(xié)議發(fā)布,歡迎轉(zhuǎn)載,演繹,但是必須保留本文的署名張洋(包含鏈接),且不得用戶商業(yè)目的。如您有任何疑問或者授權(quán)方面的協(xié)商,請(qǐng)與我聯(lián)系

 

主站蜘蛛池模板: 色五月丁香六月欧美综合 | 国产亚洲日韩在线三区| 日本一区二视频| 成人亚洲精品777777| 精品国产午夜福利精品推荐| 无码人妻精品一区二区三区下载| 丰满人妻综合一区二区三区| 国产精品久久久久野外| 久久久午夜福利精品一区二区| 久久精品国产大片免费观看| 中文无码一区二区三区在线观看 | 国产成人午夜精品福利视频| 香蕉网视频一区二区| 欧美一级黄片一区二区三区| 亚洲不卡中文字幕无码| 亚洲国产欧美在线人成app| 亚洲精品乱码久久久久久日本| 精品国产一区二区三区不卡| 国产山东熟女48嗷嗷叫| 欧美日韩一区二区精品国产| 日本在线中文字幕一区二区三区| 影音先锋女人aa鲁色资源| 99久久婷婷国产一区二区三区| 五码一区二区三区在线观看视频| 亚洲久热无码av中文字幕| 成人伊人青草久久综合网| 嫖妓丰满肥熟妇在线精品| 国产福利一区二区三区在线视频| 午夜丰满少妇性开放视频| 国产精品久久福利网站| 亚洲国产av玩弄放荡人妇系列| 亚洲成a人片在线观看www| 欧美日韩一区二区三区不卡视频 | 亚洲国产精品久久久久婷婷图片| 上司人妻互换hd无码| 国产精品久久久福利| 亚洲国产成人精品av在线| 国产在线激情视频播放一区 | 亚洲综合欧美在线…| 亚洲一区二区高清电影| 国产乱码精品一品二品|