国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

哈希摘要算法

tain335 / 3398人閱讀

摘要:哈希摘要算法哈希函數(shù)也稱散列函數(shù),是一種根據(jù)任意長度數(shù)據(jù)計(jì)算出固定簽名長度的算法,比如,系列。除了算法,還存在很多其他形式的哈希函數(shù)算法,比如系列,他們的設(shè)計(jì)思路大體相同。

前言

最近在看一些NPM庫的時(shí)候總是看到各種哈希簽名算法,之前工作中也有用到過簽名算法,但并沒有深入理解過其中的原理,于是找了點(diǎn)資料稍微了解了一下,總結(jié)了這篇文章。

哈希摘要算法

哈希函數(shù)(也稱散列函數(shù)),是一種根據(jù)任意長度數(shù)據(jù)計(jì)算出固定簽名長度的算法,比如MD5,SHA系列。

哈希簽名摘要算法特點(diǎn)

不是加密算法,而是一種摘要算法

不可逆,“單向”函數(shù)

簽名長度固定

存在2的N次方種結(jié)果,N表示簽名長度

以MD5為例

MD5是由美國密碼學(xué)家羅納德·李維斯特(Ronald Linn Rivest)設(shè)計(jì)一種加密算法。

128個(gè)bits長度,也就是16個(gè)字節(jié)

輸出結(jié)果由為“0-F”字符組成,不區(qū)分大小寫

存在2的128次方種輸出結(jié)果

MD5算法
一、源數(shù)據(jù)處理

計(jì)算原文長度(bits)對512求余的結(jié)果,需要填充原文使得原文對512求余的結(jié)果等于448, 填充的方法是第一位填充1,其余位填充0。填充完后,信息的長度為512 * N + 448。

剩余64bits存儲空間用來填充源信息長度,填充在448byte 數(shù)據(jù)之后。

最終經(jīng)過處理后的數(shù)據(jù)長度為 512 * N。

動(dòng)手畫了一張簡單的圖來說明:

二、處理數(shù)據(jù)

1、數(shù)據(jù)進(jìn)行處理前,會定義4個(gè)常量,作為初始值
這4個(gè)常量分別是

var a = 0x67452301;
var b = 0xEFCDAB89;
var c = 0x98BADCFE;
var d = 0x10325476;

翻譯成二進(jìn)制就是

var a =  1732584193;
var b = -271733879;
var c = -1732584194;
var d =  271733878;

2、將處理后的數(shù)據(jù),外循環(huán)處理N次,N為第一步中512的整數(shù)倍。
每次外循環(huán)處理的會產(chǎn)生新的“a、b、c、d”值,每次新產(chǎn)生的“a、b、c、d”值會再一次提供給下一次外循環(huán)使用

3、在每個(gè)外循環(huán)中又進(jìn)行內(nèi)循環(huán)處理64次,在這64次數(shù)據(jù)處理中會不停的將 512 bytes 數(shù)據(jù)中的 16個(gè)小單元不停的通過4個(gè)函數(shù)進(jìn)行交叉處理,共計(jì)進(jìn)行64輪計(jì)算。

4、最終生成新的“a、b、c、d”,新的“a、b、c、d”分別是占用32bytes的數(shù)據(jù)

5、最終生成的“a、b、c、d”轉(zhuǎn)換為對應(yīng)的ascll占用的字節(jié),32 bytes * 4 = 128 bytes, 一個(gè)字節(jié)占用8個(gè)bytes, 也就是16個(gè)字節(jié),16個(gè)字節(jié)轉(zhuǎn)換為ASCII碼,再將ASCII碼轉(zhuǎn)換為16進(jìn)制數(shù)據(jù),即可得到一個(gè)32個(gè)字節(jié)長度的hash值。

內(nèi)外循環(huán)代碼

function binl_md5(x, len) {
    /* append padding */
    x[len >> 5] = x[len >> 5] | 0x80 << (len % 32);
    x[(((len + 64) >>> 9) << 4) + 14] = len;    

    var i, olda, oldb, oldc, oldd,
        a =  1732584193,
        b = -271733879,
        c = -1732584194,
        d =  271733878;
    
    // 每次計(jì)算位移值,可以理解為是常量
    var ffShift = [7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22];
    var ggShift = [5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20];
    var hhShift = [4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23];
    var iiShift = [6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21];

    // Todo: 四個(gè)字節(jié)一組,每個(gè)組別之間不停的交叉計(jì)算,不停的根據(jù)已計(jì)算出來的值多次計(jì)算賦值
    // x[i]裝的是4個(gè)字節(jié)的數(shù)據(jù)
    // x.length 為 512 * N / 32
    // i += 16 每512bits長度的數(shù)據(jù)分為了16組,而每次循環(huán)的計(jì)算單位是以512為一個(gè)單元的,所以每次都是+16 
    for (i = 0; i < x.length; i += 16) {
        olda = a;
        oldb = b;
        oldc = c;
        oldd = d;

        // 64輪計(jì)算中包含原始“a、b、c、d”值。 
        // 以及位移值,以及一個(gè)計(jì)算常量,這兩個(gè)是MD5規(guī)范中所定義的常量
        a = md5_ff(a, b, c, d, x[i],      ffShift[0], -680876936);
        d = md5_ff(d, a, b, c, x[i +  1], ffShift[1], -389564586);
        c = md5_ff(c, d, a, b, x[i +  2], ffShift[2],  606105819);
        b = md5_ff(b, c, d, a, x[i +  3], ffShift[3], -1044525330);
        a = md5_ff(a, b, c, d, x[i +  4], ffShift[4], -176418897);
        d = md5_ff(d, a, b, c, x[i +  5], ffShift[5],  1200080426);
        c = md5_ff(c, d, a, b, x[i +  6], ffShift[6], -1473231341);
        b = md5_ff(b, c, d, a, x[i +  7], ffShift[7], -45705983);
        a = md5_ff(a, b, c, d, x[i +  8], ffShift[8],  1770035416);
        d = md5_ff(d, a, b, c, x[i +  9], ffShift[9], -1958414417);
        c = md5_ff(c, d, a, b, x[i + 10], ffShift[10], -42063);
        b = md5_ff(b, c, d, a, x[i + 11], ffShift[11], -1990404162);
        a = md5_ff(a, b, c, d, x[i + 12], ffShift[12],  1804603682);
        d = md5_ff(d, a, b, c, x[i + 13], ffShift[13], -40341101);
        c = md5_ff(c, d, a, b, x[i + 14], ffShift[14], -1502002290);
        b = md5_ff(b, c, d, a, x[i + 15], ffShift[15],  1236535329);

        a = md5_gg(a, b, c, d, x[i +  1], ggShift[0], -165796510);
        d = md5_gg(d, a, b, c, x[i +  6], ggShift[1], -1069501632);
        c = md5_gg(c, d, a, b, x[i + 11], ggShift[2],  643717713);
        b = md5_gg(b, c, d, a, x[i],      ggShift[3], -373897302);
        a = md5_gg(a, b, c, d, x[i +  5], ggShift[4], -701558691);
        d = md5_gg(d, a, b, c, x[i + 10], ggShift[5],  38016083);
        c = md5_gg(c, d, a, b, x[i + 15], ggShift[6], -660478335);
        b = md5_gg(b, c, d, a, x[i +  4], ggShift[7], -405537848);
        a = md5_gg(a, b, c, d, x[i +  9], ggShift[8],  568446438);
        d = md5_gg(d, a, b, c, x[i + 14], ggShift[9], -1019803690);
        c = md5_gg(c, d, a, b, x[i +  3], ggShift[10], -187363961);
        b = md5_gg(b, c, d, a, x[i +  8], ggShift[11],  1163531501);
        a = md5_gg(a, b, c, d, x[i + 13], ggShift[12], -1444681467);
        d = md5_gg(d, a, b, c, x[i +  2], ggShift[13], -51403784);
        c = md5_gg(c, d, a, b, x[i +  7], ggShift[14],  1735328473);
        b = md5_gg(b, c, d, a, x[i + 12], ggShift[15], -1926607734);

        a = md5_hh(a, b, c, d, x[i +  5], hhShift[0], -378558);
        d = md5_hh(d, a, b, c, x[i +  8], hhShift[1], -2022574463);
        c = md5_hh(c, d, a, b, x[i + 11], hhShift[2],  1839030562);
        b = md5_hh(b, c, d, a, x[i + 14], hhShift[3], -35309556);
        a = md5_hh(a, b, c, d, x[i +  1], hhShift[4], -1530992060);
        d = md5_hh(d, a, b, c, x[i +  4], hhShift[5],  1272893353);
        c = md5_hh(c, d, a, b, x[i +  7], hhShift[6], -155497632);
        b = md5_hh(b, c, d, a, x[i + 10], hhShift[7], -1094730640);
        a = md5_hh(a, b, c, d, x[i + 13], hhShift[8],  681279174);
        d = md5_hh(d, a, b, c, x[i],      hhShift[9], -358537222);
        c = md5_hh(c, d, a, b, x[i +  3], hhShift[10], -722521979);
        b = md5_hh(b, c, d, a, x[i +  6], hhShift[11],  76029189);
        a = md5_hh(a, b, c, d, x[i +  9], hhShift[12], -640364487);
        d = md5_hh(d, a, b, c, x[i + 12], hhShift[13], -421815835);
        c = md5_hh(c, d, a, b, x[i + 15], hhShift[14],  530742520);
        b = md5_hh(b, c, d, a, x[i +  2], hhShift[15], -995338651);

        a = md5_ii(a, b, c, d, x[i],      iiShift[0], -198630844);
        d = md5_ii(d, a, b, c, x[i +  7], iiShift[1],  1126891415);
        c = md5_ii(c, d, a, b, x[i + 14], iiShift[2], -1416354905);
        b = md5_ii(b, c, d, a, x[i +  5], iiShift[3], -57434055);
        a = md5_ii(a, b, c, d, x[i + 12], iiShift[4],  1700485571);
        d = md5_ii(d, a, b, c, x[i +  3], iiShift[5], -1894986606);
        c = md5_ii(c, d, a, b, x[i + 10], iiShift[6], -1051523);
        b = md5_ii(b, c, d, a, x[i +  1], iiShift[7], -2054922799);
        a = md5_ii(a, b, c, d, x[i +  8], iiShift[8],  1873313359);
        d = md5_ii(d, a, b, c, x[i + 15], iiShift[9], -30611744);
        c = md5_ii(c, d, a, b, x[i +  6], iiShift[10], -1560198380);
        b = md5_ii(b, c, d, a, x[i + 13], iiShift[11],  1309151649);
        a = md5_ii(a, b, c, d, x[i +  4], iiShift[12], -145523070);
        d = md5_ii(d, a, b, c, x[i + 11], iiShift[13], -1120210379);
        c = md5_ii(c, d, a, b, x[i +  2], iiShift[14],  718787259);
        b = md5_ii(b, c, d, a, x[i +  9], iiShift[15], -343485551);

        a = safe_add(a, olda);
        b = safe_add(b, oldb);
        c = safe_add(c, oldc);
        d = safe_add(d, oldd);
    }
    // 最終生成4個(gè)占用32 bytes控制的值
    return [a, b, c, d];
}

四輪計(jì)算線性函數(shù)

F(X,Y,Z) =(X&Y)|((~X)&Z) 
G(X,Y,Z) =(X&Z)|(Y&(~Z)) 
H(X,Y,Z) =X^Y^Z 
I(X,Y,Z)=Y^(X|(~Z)) 

6、第五點(diǎn)可以解釋為什么生成的hash值中只會包含“0-F”,且不區(qū)分大小寫的原因,長度為16。

function rstr2hex(input) {
    var hex_tab = "0123456789abcdef",
        output = "",
        x,
        i;
    for (i = 0; i < input.length; i += 1) {
        x = input.charCodeAt(i);
        output += hex_tab.charAt((x >>> 4) & 0x0F) +
            hex_tab.charAt(x & 0x0F); x:${input.charCodeAt(i)}, output: ${output}`);
    }
    return output;
}

以上代碼來自 https://github.com/blueimp/JavaScript-MD5,稍有改動(dòng)。

適用場景:

私密數(shù)據(jù)加密,比如用戶密碼一般都不會明文存儲,而是通過加密后存入數(shù)據(jù)庫

賭場開盤前將開票結(jié)果公布,開盤后通過簽名對比校驗(yàn)是否存在作弊行為

檢測文件是否下載完成,比如迅雷下載

...

如何破解

MD5中,雖然由源文可以推導(dǎo)出簽名,反過來,并不能由簽名推導(dǎo)出源文。但MD5并不是堅(jiān)不可摧,目前有兩種破解方式

碰撞法,雖然MD5簽名存在2的128次方種輸出結(jié)果,但每個(gè)簽名對應(yīng)的原文并不是唯一的,只要計(jì)算機(jī)性能夠強(qiáng)大,給予充足的時(shí)間,總能找到能輸出相同簽名的數(shù)據(jù)源。

映射法,把常規(guī)字符串對應(yīng)的簽名存儲,比如常用的“123456”,“abcdefg”等。當(dāng)?shù)玫組D5簽名時(shí),就可以映射出源數(shù)據(jù)。

如何防范:

使用安全性更高的SHA256,并不是說SHA256不能被破解,只是相對于MD5來說算法步驟更多,也更復(fù)雜,破解難度更大。

源數(shù)據(jù) + KEY,比如“123456”加上KEY就變成了“123456@#DFF23DS”,其中“@#DFF23DS”就是服務(wù)端存儲的KEY。“源數(shù)據(jù) + KEY” => 簽名。

源數(shù)據(jù) + KEY + 動(dòng)態(tài)數(shù)據(jù),KEY有可能會被猜到,如果再加上動(dòng)態(tài)數(shù)據(jù)的話,破解難度會進(jìn)一步提升,比如用戶名、動(dòng)態(tài)密碼。“源數(shù)據(jù) + KEY + 動(dòng)態(tài)密碼” => 簽名。

多次MD5,MD5("123456")很容易被猜到,MD5(MD5("123456")),將MD5后的簽名再進(jìn)行一次MD5呢,如果進(jìn)行三次,十次,是不是破解的難度會更大,當(dāng)然這么做會增加計(jì)算時(shí)間,需要權(quán)衡。

其他:

中文編碼需要轉(zhuǎn)碼,否則前端與后端編碼后的值可能不一致。

除了MD5算法,還存在很多其他形式的哈希函數(shù)算法,比如SHA系列,他們的設(shè)計(jì)思路大體相同。

參考資料

阮一峰講解操作符
按位移動(dòng)操作符
各種進(jìn)制在線轉(zhuǎn)換
維基百科MD5
維基百科SHA2
NPM MD5

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/103457.html

相關(guān)文章

  • 當(dāng)我們在談?wù)撉岸思用軙r(shí),我們在談些什么

    摘要:所以我們今天只談前端加密,一個(gè)部分人認(rèn)為沒有意義的工作。在中,認(rèn)證過程使用了非對稱加密算法,非認(rèn)證過程中使用了對稱加密算法。非對稱加密上文中我們討論了前端的哈希加密以及應(yīng)用的場景。 showImg(https://segmentfault.com/img/bVAhTC); 當(dāng)然在談安全。 前端安全是Web安全的一部分,常見的安全問題會有XSS、CSRF、SQL注入等,然而這些已經(jīng)在程師...

    wizChen 評論0 收藏0
  • python模塊之hashlib

    摘要:使用算法名稱構(gòu)造函數(shù)較使用更快所有平臺的模塊都支持的算法的名稱集合。的結(jié)果集總是結(jié)果集的子集對象的字節(jié)長度對象的內(nèi)部塊大小對象的名稱傳遞類字節(jié)參數(shù)通常是更新對象。表示的哈希摘要算法的名稱,比如或。表示迭代次數(shù),基于算法以及機(jī)器計(jì)算能力設(shè)置。 hashlib模塊實(shí)現(xiàn)了多種安全哈希和信息摘要算法的通用接口,包括FIPS中定義的SHA1, SHA224, SHA256, SHA384, SH...

    luodongseu 評論0 收藏0
  • 區(qū)塊鏈學(xué)習(xí)之密碼學(xué)安全技術(shù)(五)

    摘要:非對稱加密算法的安全性往往需要基于數(shù)學(xué)問題來保障,目前主要有基于大數(shù)質(zhì)因子分解離散對數(shù)橢圓曲線等經(jīng)典數(shù)學(xué)難題進(jìn)行保護(hù)。消息認(rèn)證碼基于對稱加密,可以用于對消息完整性進(jìn)行保護(hù)。 Hash 算法與數(shù)字摘要 Hash (哈希或散列)算法它能將任意長度的二進(jìn)制明文串映射為較短的(通常是固定長度的)二進(jìn)制串(Hash值),并且不同的明文很難映射為相同的Hash值。 Hash 定義 Hash (哈希...

    aboutU 評論0 收藏0
  • 區(qū)塊鏈記賬原理

    摘要:本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接區(qū)塊鏈記賬原理原文已更新,請讀者前往原文閱讀區(qū)塊鏈?zhǔn)且粋€(gè)基于密碼學(xué)安全的分布式賬本,是一個(gè)方便驗(yàn)證,不可篡改的賬本。哈希函數(shù)在講區(qū)塊鏈記賬之前,先說明一下哈希函數(shù)。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:區(qū)塊鏈記賬原理原文已更新,請讀者前往原文閱讀 區(qū)塊鏈(1.0)是一個(gè)基于密碼學(xué)安全的分布式賬本,是一個(gè)方便驗(yàn)證,不可篡改的賬本。 通常認(rèn)為與智能合約...

    mumumu 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<