2010-06-03 58 views
9

我正在開發一個內部驗證用戶的小型Web應用程序。一旦用戶通過身份驗證,我的網絡應用程序會將一些信息(如用戶ID和人員姓名)傳遞給第三方Web應用程序。第三方開發人員建議我們對值進行散列和加鹽。散列和醃製值

原諒我的無知,但究竟是什麼意思?

我正在用Java編寫應用程序。所以我打算做的是將用戶ID,Person的名稱和一些Math.random()值散列爲Apache Commons Digest Utils SHA512的鹽值,並將散列字符串與用戶ID和人員姓名一起傳遞。

這是標準做法嗎? 我應該通過鹽的第三方以及正確?

+0

我很高興,這個問題的答案如此之多,跳過了標題並回答了無關的問題:「密碼的含義是什麼?」。 – dimo414 2010-06-03 21:49:53

回答

14

鹽通常用於安全地存儲密碼散列。散列用於存儲或通信的密碼(以使其不能被其他人閱讀)易於使用rainbow tables進行解碼。現在,當您向密碼添加一個隨機字符串,但將該字符串與散列一起存儲時,這變得更加困難。計算這個新的哈希看起來像:

hash(password + salt) 

甚至

hash(hash(password) + salt) 

要安全地登錄到第三方網站,可以發送用戶ID,鹽漬哈希(從上面),以及您所用的鹽(如果沒有給出)。根據網站存儲密碼的方式,您可以爲自己生成鹽,或者您可以從中請求鹽。

一種選擇是首先將用戶ID發送到網站,然後讓它用鹽迴應,然後將hash(password+salt))發送回網站。

+0

AFAIK做兩個散列(就像你的第二個例子)將會更弱,密碼學。我認爲原因在於密碼中的任何£%%^&字符將被更改爲字母/數字,因此它們在彩虹表中所需的值較少。 – 2010-06-03 21:26:37

+0

我在印象之下,即使使用正確的會話ID,第三方網站也無法訪問我的會話對象?也許我錯了? – Avanst 2010-06-03 21:26:52

+0

啊,對不起,我誤解了你的問題。我將編輯我的口水。 – Marc 2010-06-03 21:28:12

1

一旦用戶通過驗證我的web應用程序 然後傳遞到第三 黨的web應用程序的一些信息,如 用戶ID和個人的名字。第三方開發人員建議我們對值進行散列和加鹽。

這聽起來不對。哈希是單向操作。你不能把一個哈希的結果和神聖的純文本從它

什麼我打算做的是哈希 的用戶ID,人的名字,而作爲鹽的一些 的Math.random()值

對於任何給定的明文,您需要使用相同的鹽,否則生成的散列值將會不同。因此,如果您要使用隨機或生成的鹽,則需要將其與密碼哈希一起存儲。

使用SHA-256和SHA-512是好的,是什麼NIST recommends

+2

你是什麼意思,對於任何給定的明文,你需要使用相同的鹽?鹽的完整點是相同的明文可以有不同的*散列(明文+鹽)*結果的萬億億次,使得「彩虹表」的攻擊變得不可能。例如在Un * x系統上,您可以讓兩個用戶選擇相同的密碼,但該密碼會有兩個不同的哈希值,因爲使用了不同的鹽值(沿着哈希密碼保存)。 – NoozNooz42 2010-06-03 21:36:31

+1

我認爲你誤解了他所說的 - 如果鹽不同,即使使用相同的明文,結果散列也會不同。 – dimo414 2010-06-03 21:46:50

8

在Java中,你可以這樣做:

import org.apache.commons.codec.digest.DigestUtils; 
import org.apache.commons.lang.RandomStringUtils; 

/** 
* SHA1-hash the password with the user's salt. 
* 
* @param password 
*/ 
public void setPassword(String password) 
{ 
    if (password.equals(this.password)) 
    { 
     return; 
    } 

    if (passwordSalt == null || passwordSalt.equals("")) 
    { 
     passwordSalt = RandomStringUtils.randomAscii(20); 
    } 

    this.password = DigestUtils.shaHex(password + passwordSalt); 
} 

/** 
* Check if a given password is correct. 
* 
* @param givenPassword 
* @return True is correct, else false. 
*/ 
public boolean checkPassword(String givenPassword) 
{ 
    return (password.equals(DigestUtils.shaHex(givenPassword + passwordSalt))); 
} 

則口令也無法讀取,即使黑客竊取您的D B。

+0

您還需要返回passwordSalt,也許還需要一個getter。 – 2010-06-03 22:37:46

+0

使用** apache commons codec lib ** +1!從這裏下載apache.org:[commons-codec-1.9.jar](http://commons.apache.org/proper/commons-codec/) – 2014-04-26 11:30:36

0

鹽的整點是使用所謂的「彩虹表」進行攻擊不可行(從概率的角度來看:如果採取足夠大的散列,那麼實際上不可能預先計算彩虹表)。

http://en.wikipedia.org/wiki/Rainbow_table

而不是僅僅做一個哈希(一個)和存儲數據的哈希:

:460526e74fd6a25b525e642db2f756a4: 

你做哈希(A +鹽)你存儲哈希和鹽(鹽可以隨機挑選):

:cdd5bc3f05f6a76f6c82af728b2c555c:346884e6e35be: 
3

只是一個人擡頭,那裏是有關如何處理鹽的一些錯誤信息。儲存鹽是正常的和正常的。每個密碼都應該有它自己的鹽,它與它一起以純文本形式存儲。這意味着對於已經竊取散列密碼數據庫的人來說,使用預先計算的散列表對其進行解密會更困難。

至於如果你應該發送第三方鹽,我必須有更多的信息。無論誰在驗證過程中採用客戶端提供的密碼,對其進行哈希處理並將其與預哈希版本進行比較,都需要salt,這樣客戶端提供的用於身份驗證的密碼可以與之前的哈希完全相同。

1

我會看看你是否從這個第三方應用程序中找不到更多信息或示例。你所描述的東西看起來不像通常的做法,而且根據你所說的話,說實話根本就沒有多大意義。

你在你的程序中驗證用戶(幾個答案似乎是解決這個問題,是的,你應該將你的用戶密碼存儲爲醃過的哈希值,但這是一個完整的問題),然後,正在將一些信息傳遞給第三方應用程序。現在,這取決於這個應用程序應該做什麼/知道什麼。例如,如果它需要知道用戶標識,那麼在提交之前不能對其進行哈希/填充,因爲該應用永遠無法獲取原始用戶標識。另一方面,如果應用程序只需要某種標識符來識別請求,並且哈希userID + userName只是一個建議,那麼這確實有意義,您基本上生成一個用戶唯一但不可解碼的字符串爲第三方應用程序使用,基本上作爲會話密鑰。

如果第二條路線是他們想讓你做的事情,那麼處理請求有點奇怪(而且不是非常安全),但對我來說似乎是對的。

所以就像我說的那樣,看看你是否可以找到一些例子,或者即使你想在這裏發佈更多關於這個應用程序的信息,我們可以看看自己。