G8.3 實(shí)現(xiàn)不可逆加密 - 用Go語言 Golang實(shí)現(xiàn)

前兩節(jié)介紹的加密方法都屬于“可逆”的加密算法,因?yàn)榧用芎蟮拿芪慕?jīng)過解密的過程就可以還原出原文册招。還有一類加密算法屬于“不可逆”的加密算法岔激,是指一般無法進(jìn)行正常解密還原出原文的加密算法。


不可逆加密算法的應(yīng)用場景也有很多是掰,最典型的是服務(wù)端保存用戶登錄密碼的方式虑鼎。從保護(hù)用戶隱私角度考慮,服務(wù)器端不應(yīng)該存儲用戶的登錄密碼原文键痛,也不應(yīng)該保存可逆加密后的密文(因?yàn)橐部梢员唤饷苓€原)炫彩,這時(shí)候?qū)嵺`中常用的方法是在服務(wù)器保存密碼時(shí)將其用不可逆的算法轉(zhuǎn)換成密文存儲,下次用戶登錄時(shí)服務(wù)器將發(fā)來的用戶密碼以同樣的不可逆算法加密后再與保存的密碼密文做比對來判斷是否相同絮短。


從這個例子也可以看出江兢,不可逆加密算法一般要滿足這個要求:同樣的明文用同樣的方式加密后,得到的密文必須是一樣丁频,否則就無法用于比對了杉允。


最簡單的不可逆加密算法可能就是取模算法了,例如18 % 5 的結(jié)果是3席里,而23 % 5的結(jié)果也是3叔磷,如果18和23代表明文,“% 5”這個取模操作(也就是求對于5的余數(shù))代表加密算法奖磁,3代表加密后的密文改基,那么顯然這個加密算法是不可逆的,因?yàn)閺拿芪摹?”無法確定原文是18還是23(甚至還可能是其他更多的數(shù)字)署穗,而任何數(shù)字對5取模的結(jié)果都是不變的寥裂。那么該算法如果用于對密碼加密,可以將密碼轉(zhuǎn)換后的字節(jié)切片中的每個字節(jié)數(shù)值對5取模后形成新的密文字節(jié)切片案疲,服務(wù)器端保存這個密文就可以了封恰,以后用戶登錄時(shí)傳上來的密碼做同樣的加密操作,得到的結(jié)果與保存的密文應(yīng)該是一致的褐啡。


當(dāng)然诺舔,取模操作作為加密方法來說加密強(qiáng)度太低,實(shí)際應(yīng)用中用的最多的不可逆加密算法是MD5算法,該算法應(yīng)用了散列函數(shù)的原理低飒,可以將任何數(shù)據(jù)轉(zhuǎn)換成固定長度的字節(jié)序列(一般是16個字節(jié))许昨,并且與取模操作一樣具有原文對應(yīng)到密文的唯一性。


取模操作也可以看做散列函數(shù)的一種褥赊,可以將任何數(shù)據(jù)散列到[0, n)的范圍內(nèi)(n是取模的模數(shù))糕档。散列函數(shù)一般都具備這樣的特性:原始數(shù)據(jù)與散列后的數(shù)據(jù)是多對一的關(guān)系,即同樣的原始數(shù)據(jù)用同樣的散列函數(shù)處理后必然得到同樣的結(jié)果拌喉,但同樣的結(jié)果不一定對應(yīng)同一個原始數(shù)據(jù)速那。這也是為什么大多數(shù)不可逆算法使用散列函數(shù)作為核心方法的原因。


下面的代碼演示了如何使用Go語言中的crypto/md5等包來實(shí)現(xiàn)MD5加密算法尿背。


package main


import (

? "crypto/md5"

? "encoding/hex"

? "io"

? "log"

? "os"

? "strings"

? t "github.com/topxeq/goexamples/tools"

)


func main() {


? //原始字符串

? originalTextT := "測試字符串"


? //對原始字符串生成md5碼端仰,md5BytesArrayT是[16]byte類型的數(shù)組

? md5BytesArrayT :=md5.Sum([]byte(originalTextT))


? //將數(shù)組轉(zhuǎn)換為切片

? md5BytesT := md5BytesArrayT[:]


? t.Printfln("md5字節(jié)切片(16個字節(jié)): %#v", md5BytesT)


? //將md5字節(jié)切片轉(zhuǎn)換為16進(jìn)制的文本,將有32個字符

? //并轉(zhuǎn)換為全大寫字母

? md5TextT := strings.ToUpper(hex.EncodeToString(md5BytesT))


? t.Printfln("md5文本(32位): %#v", md5TextT)


? //用流式方法對字符串進(jìn)行md5編碼

? md5Encoder := md5.New()


? //向md5Encoder中寫入字符串

? io.WriteString(md5Encoder, originalTextT)


? //調(diào)用Sum函數(shù)進(jìn)行md5編碼田藐,并轉(zhuǎn)換為十六進(jìn)制字符串

? md5TextT = hex.EncodeToString(md5Encoder.Sum(nil))


? t.Printfln("流式編碼的md5文本(小寫): %#v", md5TextT)


? //直接用流式方法對一個文件進(jìn)行md5編碼

? fileT, errT := os.Open(`c:\test\long.txt`)


? if errT != nil {

?????? log.Fatal(errT)

? }


? defer fileT.Close()


? md5Encoder = md5.New()


? //帶有初始化語句的條件判斷

? if _, errT = io.Copy(md5Encoder, fileT); errT!= nil {

?????? log.Fatal(errT)

? }


? t.Printfln("文件的md5碼:%x", md5Encoder.Sum(nil))

}

代碼 14?3 MD5加密示例


代碼14?3中已經(jīng)有詳盡的解釋荔烧,再附加幾點(diǎn)解釋如下:


-> 代碼中用到的md5包中的函數(shù)最主要的是md5.Sum函數(shù),該函數(shù)實(shí)現(xiàn)了將任意一個字節(jié)切片編碼為MD5汽久,編碼結(jié)果的數(shù)據(jù)類型是[16]byte鹤竭,即16個字節(jié)的字節(jié)數(shù)組;

->?由于字節(jié)數(shù)組與字節(jié)切片并不是同一個類型景醇,所以還需要進(jìn)行轉(zhuǎn)換诺擅,將[16]byte類型的數(shù)據(jù)轉(zhuǎn)換為[]byte類型才能符合后面hex.EncodeToString等函數(shù)的傳入?yún)?shù)類型要求;

->?目前一般使用時(shí)都是用MD碼的十六進(jìn)制文本形式啡直,這會有32個字符長度烁涌;

->?代碼后面也演示了如何用流式方法來直接編碼一個字符串為MD碼以及直接編碼一個文件;md5.New函數(shù)將新建一個MD5的編碼器(hash.Hash類型)酒觅,該編碼器支持流式寫入撮执,寫入完所有內(nèi)容后,調(diào)用該編碼器的Sum函數(shù)就會進(jìn)行MD5編碼舷丹;


代碼14?3的運(yùn)行結(jié)果是:


md5字節(jié)切片(16個字節(jié)): []byte{0x1f, 0x3c, 0xa0, 0x51, 0x2, 0x8d, 0x1d, 0x1e, 0x95, 0xa6, 0xf4, 0xe2, 0x69, 0xd7, 0x27, 0xab}

md5文本(32位): "1F3CA051028D1D1E95A6F4E269D727AB"

流式編碼的md5文本(小寫): "1f3ca051028d1d1e95a6f4e269d727ab"

文件的md5碼:9da81dede7a381a6d9fecc0cd69a81a9


可以看出抒钱,無論使用普通方式還是流式方式進(jìn)行MD5編碼,對同樣的輸入字符串的結(jié)果都是一樣的(注意颜凯,十六進(jìn)制文本的大小寫一般在各個系統(tǒng)中都可以識別谋币,目前的趨勢更多的是使用小寫形式)。


類似MD5這樣的不可逆加密症概,也不需要使用密碼就可以直接進(jìn)行加密蕾额。


最后順便提一下胁附,任何加密理論上都可以被破解谍珊,即使是不可逆的加密算法也是有辦法破解的。MD5的破解方法已經(jīng)在網(wǎng)絡(luò)上有所流傳桑包,實(shí)質(zhì)上是窮舉法的破解方式,就是不停地收集和計(jì)算各種明文的MD5編碼并將這兩者的成對保存起來调炬,然后根據(jù)保存的海量數(shù)據(jù)语盈,對MD5密文進(jìn)行反查,這需要大量的積累缰泡,消耗的資源也較大刀荒,查出來的結(jié)果也可能是多個(MD5的密文與明文是一對多的關(guān)系),但確實(shí)也算是一種方法棘钞,在此說明一下供大家了解照棋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市武翎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溶锭,老刑警劉巖宝恶,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異趴捅,居然都是意外死亡垫毙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門拱绑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來综芥,“玉大人,你說我怎么就攤上這事猎拨“蛎辏” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵红省,是天一觀的道長额各。 經(jīng)常有香客問我,道長吧恃,這世上最難降的妖魔是什么虾啦? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮痕寓,結(jié)果婚禮上傲醉,老公的妹妹穿的比我還像新娘。我一直安慰自己呻率,他們只是感情好硬毕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著礼仗,像睡著了一般昭殉。 火紅的嫁衣襯著肌膚如雪苞七。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天挪丢,我揣著相機(jī)與錄音蹂风,去河邊找鬼。 笑死乾蓬,一個胖子當(dāng)著我的面吹牛惠啄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播任内,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撵渡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了死嗦?” 一聲冷哼從身側(cè)響起趋距,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎越除,沒想到半個月后节腐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摘盆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年翼雀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孩擂。...
    茶點(diǎn)故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡狼渊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出类垦,到底是詐尸還是另有隱情狈邑,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布蚤认,位于F島的核電站官地,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烙懦。R本人自食惡果不足惜驱入,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氯析。 院中可真熱鬧亏较,春花似錦、人聲如沸掩缓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽你辣。三九已至巡通,卻和暖如春尘执,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宴凉。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工誊锭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弥锄。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓丧靡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親籽暇。 傳聞我的和親對象是個殘疾皇子温治,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容