1. 程式人生 > >【轉載】關於Hash

【轉載】關於Hash

基礎 ati 自己的 set 求逆 保密 不同 估計 概率

這個HASH算法不是大學裏數據結構課裏那個HASH表的算法。這裏的HASH算法是密碼學的基礎,比較常用的有MD5和SHA,最重要的兩條性質,就是不可逆無沖突
所謂不可逆,就是當你知道x的HASH值,無法求出x;
所謂無沖突,就是當你知道x,無法求出一個y, 使x與y的HASH值相同。

這兩條性質在數學上都是不成立的。因為一個函數必然可逆,且由於HASH函數的值域有限,理論上會有無窮多個不同的原始值,它們的hash值都相同。MD5和SHA做到的,是求逆和求沖突在計算上不可能,也就是正向計算很容易,而反向計算即使窮盡人類所有的計算資源都做不到。

我覺得密碼學的幾個算法(HASH、對稱加密、公私鑰)是計算機科學領域最偉大的發明之一,它授予了弱小的個人在強權面前信息的安全(而且是絕對的安全)。舉個例子,只要你一直使用https與國外站點通訊,並註意對方的公鑰沒有被篡改,G**W可以斷開你的連接,但它永遠不可能

知道你們的傳輸內容是什麽。

順便說一下,王小雲教授曾經成功制造出MD5的碰撞,即md5(a) = md5(b)。這樣的碰撞只能隨機生成,並不能根據一個已知的a求出b(即並沒有破壞MD5的無沖突特性)。但這已經讓他聲名大噪了

作者:蔣又新
鏈接:https://www.zhihu.com/question/20820286/answer/16319538

hash(散列、雜湊)函數,是將任意長度的數據映射到有限長度的域上。直觀解釋起來,就是對一串數據m進行雜糅,輸出另一段固定長度的數據h,作為這段數據的特征(指紋)。
也就是說,無論數據塊m有多大,其輸出值h為固定長度。到底是什麽原理?將m分成固定長度(如128位),依次進行hash運算,然後用不同的方法叠代即可(如前一塊的hash值與後一塊的hash值進行異或)。如果不夠128位怎麽辦?用0補全或者用1補全隨意,算法中約定好就可以了。
原問題回答完畢。但是既然要說hash算法,不妨說的更透徹些。
=================分割線==========
由於用途的不同,hash在數據結構中的含義和密碼學中的含義並不相同,所以在這兩種不同的領域裏,算法的設計側重點也不同。

預備小知識:
抗碰撞能力:對於任意兩個不同的數據塊,其hash值相同的可能性極小;對於一個給定的數據塊,找到和它hash值相同的數據塊極為困難。
抗篡改能力:對於一個數據塊,哪怕只改動其一個比特位,其hash值的改動也會非常大。
在用到hash進行管理的數據結構中,比如hashmap,hash值(key)存在的目的是加速鍵值對的查找,key的作用是為了將元素適當地放在各個桶裏,對於抗碰撞的要求沒有那麽高。換句話說,hash出來的key,只要保證value大致均勻的放在不同的桶裏就可以了。但整個算法的set性能,直接與hash值產生的速度有關,所以這時候的hash值的產生速度就尤為重要,以JDK中的String.hashCode()方法為例:

    public int hashCode() {
        int h = hash;
        //hash default value : 0 
        if (h == 0 && value.length > 0) {
        //value : char storage
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

很簡潔的一個乘加叠代運算,在不少的hash算法中,使用的是異或+加法進行叠代,速度和前者差不多。

在密碼學中,hash算法的作用主要是用於消息摘要和簽名,換句話說,它主要用於對整個消息的完整性進行校驗。舉個例子,我們登陸知乎的時候都需要輸入密碼,那麽知乎如果明文保存這個密碼,那麽黑客就很容易竊取大家的密碼來登陸,特別不安全。那麽知乎就想到了一個方法,使用hash算法生成一個密碼的簽名,知乎後臺只保存這個簽名值。由於hash算法是不可逆的,那麽黑客即便得到這個簽名,也絲毫沒有用處;而如果你在網站登陸界面上輸入你的密碼,那麽知乎後臺就會重新計算一下這個hash值,與網站中儲存的原hash值進行比對,如果相同,證明你擁有這個賬戶的密碼,那麽就會允許你登陸。銀行也是如此,銀行是萬萬不敢保存用戶密碼的原文的,只會保存密碼的hash值而而已。
在這些應用場景裏,對於抗碰撞和抗篡改能力要求極高,對速度的要求在其次。一個設計良好的hash算法,其抗碰撞能力是很高的。以MD5為例,其輸出長度為128位,設計預期碰撞概率為技術分享圖片,這是一個極小極小的數字——而即便是在MD5被王小雲教授破解之後,其碰撞概率上限也高達技術分享圖片,也就是說,至少需要找技術分享圖片次才能有1/2的概率來找到一個與目標文件相同的hash值。而對於兩個相似的字符串,MD5加密結果如下:

MD5("version1") = "966634ebf2fc135707d6753692bf4b1e";
MD5("version2") = "2e0e95285f08a07dea17e7ee111b21c8";

可以看到僅僅一個比特位的改變,二者的MD5值就天差地別了。

到這裏,讀者估計會問,有沒有可能找到這麽一個算法,如果輸出長度為128位,那麽把這128位“充分利用到”,讓它可以有技術分享圖片種不同的hash值,而且分布均勻,抗篡改能力也特別高,一點點改動就會讓hash值面目全非,一點都不浪費(這裏的表述非常不嚴格)?稍微嚴格一點表述,就是:有沒有這樣一個算法,使得對於任何一個給定的輸入,此算法都會輸出一個固定的均勻隨機的輸出?
答案是密碼學家們也至今沒有構造出著這樣一個算法,但是傾向於這個算法存在,而且有不少的密碼學算法構造和這個假設有關。這個假設的名字叫做隨機預言機(Random Oracle)。

在密碼學中,hash算法有不少有意思的改進思路,以應付不同的使用場景。例如師兄

@劉巍然-學酥

前一段時間讓我寫著玩的變色龍Hash(ChameleonHash),它有一個有趣的特性。在普通情況下,ChameleonHash可以當做普通hash算法使用,從明文(用m表示)得到的hash值(用h表示)抗碰撞能力依然特別強;但是如果使用者在計算這個hash值的時候預先計算一個值(用s表示)並保存,那麽通過這個值很容易計算出另一個hash值也為h的明文m‘ !也就是說,如果你保留這個值的話,hash算法的抗碰撞能力完全被解除了。
這意味著,如果某個網站想要作惡的話,那麽它可以很容易的替換他們自己的hash算法為ChameleonHash,方便地偽造出一個密鑰來竊取用戶的所有數據,而這個公司完全可以在對外宣傳的時候,依然聲稱對用戶信息嚴格保密——《教網站如何優雅地耍流氓》。

作者:之幽
鏈接:https://www.zhihu.com/question/26762707/answer/40119521
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

【轉載】關於Hash