2013-10-08 48 views
2

我需要Node的標準庫中的Crypto模塊。 我有處理登記表這篇文章路線:在Node/Express中哈希,鹽和保存密碼

app.post('/superadmin/add-account', function(req, res) { 

    // Shorthand variable 
    var doc = req.body; 

    crypto.randomBytes(32, function(err, buf) { 

    if (err) throw err; 

    // Sanitise and transform user input 
    ... 

    // Validate user input 
    ... 

    var errors = validator.getErrors(); 

    // Generate new object data 
    doc.salt = buf; 
    doc.pass = doc.salt + 'justForNow'; 

    console.log(doc); 

當我輸出的文檔(req.body)現在我得到的是覺得奇怪,我的一些值... 在控制檯輸出的BUF是大多由類似箱子裏面帶有問號的字符組成。它是否正確?但是當我把buf保存到doc.salt並輸出時,我得到了一些完整的東西......「Slowbuffer ae be C5 A3 E3 ....等等」

Q1:我必須做些什麼特殊的(解析它的東西?)用crypto.randomBytes()生成的鹽,然後我使用它與字符串連接或保存它?

Q2: crypto.randomBytes()函數存在於異步和同步版本中。即時通訊使用異步版本,但我真的不知道爲什麼? = PI認爲異步callbaks主要用於處理可能需要時間的I/O操作......或者我使用此函數的回調版本,因爲它實際上是一個複雜的過程,可能需要一些時間併爲som MS鎖定系統如果我使用同步版本?

Q3:我還沒有,但是我將繼續使用The Crypto模塊的散列函數對salt + password進行散列並將其保存到數據庫。我知道我必須創建一個這樣的變種:

var sha256 = crypto.createHash('sha256'); 

但我不明白我現在如何使用它。

+0

好吧,我只是試圖在buf上使用'toString()'。這似乎給了我一個更友好的用戶界面變量......但是如果'crypto.randomBytes()'不生成一個字符串?它會產生什麼樣的數據類型? –

回答

1

當您使用crypto.randomBytes()生成隨機字節時,解析字節沒有任何特殊之處,因爲它們是隨機的。隨機字節由兩個十六進制數字組成,所以如果您使用的是buffer.toString(),則該字節可以映射到00FF之間的任何UTF-8數字。

當使用randomBytes()函數時,會得到一個SlowBuffer,它是一個內部類Buffer

<SlowBuffer 76 46 14 02> 
// v F \u0014 \u0002 

如果兩個十六進制數字的UTF-8表示不存在,你會得到一個亂碼字符串:

<Buffer 96> 
// � 
<SlowBuffer 9e 94> 
// �� 

關於第二個問題,就看你是否要使用randomBytes()函數的同步版本的異步。函數使用的CPU時間量也取決於您要求的隨機字節數。如果你想要一萬億個隨機字節,你會阻塞事件循環達到相當長的時間,但是如果你想要十個隨機字節,那隻需要幾毫秒。

大多數情況下,如果您將操作放在HTTP處理程序中,則應該使用異步版本,因爲您要避免不惜一切代價阻止事件循環。這是不該做的一個例子:

app.post('/', function(req, res) { 
    crypto.randomBytes(1000000000); 
}); 

通過這樣做,您將停止服務器處理任何其他傳入的HTTP請求。

至於你的最後一個問題,你已經創建了哈希對象,但沒有更新它的數據或計算它的摘要。使用hash.update()hash.digest()分別用於散列的字符串表示:

var crypto = require('crypto'); 
var hash = crypto.createHash('sha256').update(data).digest('hex'); 

hash.update()函數接受兩個參數,數據塊和編碼,而hash.digest()接受的編碼。