2012-10-23 62 views
2

我在寫一個使用HMAC進行消息認證的web服務。我正在爲摘要準備「數據」,並且在Python和NodeJS中爲相同的「數據」獲取不同的摘要。爲HMAC準備一個字符串

我相當確信這個問題是由於編碼,但我不知道如何最好的方法。

Python代碼:

import hmac 
from hashlib import sha1 

f = open('../test.txt') 
raw = f.read() 

raw = raw.strip() 

hm = hmac.new('12345', raw, sha1) 
res = hm.hexdigest() 
print res 

>> 5bff447a0fb82f3e7572d9fde362494f1ee2c25b 

的NodeJS(咖啡)代碼:

fs = require 'fs' 
http = require 'http' 
{argv} = require 'optimist' 
crypto = require 'crypto' 

# Load the file 
file = fs.readFileSync argv.file, 'utf-8' 
file = file.trim() 

# Create the signature 
hash = crypto.createHmac('sha1', '12345').update(file).digest('hex') 
console.log(hash) 

>> a698f82ea8ff3c4e9ffe0670be2707c104d933aa 

編輯:另外,原料的長度比文件長2個字符,但我不能工作了,其中這兩個角色來自。

回答

4

這是你從文件系統中讀取數據的編碼問題並沒有任何與你使用的算法rstrip()可能有明確的角色。

當您在Python和JavaScript中處理字符串數據時,應該非常小心您的數據存儲在哪個編碼中。嘗試使用數據來處理字符串(它們特別具有編碼等屬性) ),或者與「原始數據」一樣。在閱讀和簽署數據時,您不應該關心編碼,並儘可能使用數據作爲您的語言中的「原始」。

幾點需要注意:

  • 文件系統存儲「原始」字節,一無所知的內容和文件的編碼。此外,對於某些文件(例如,jpeg),「編碼」概念是毫無價值的
  • 這同樣適用於加密算法。他們使用原始字節並且對其「字符表示」一無所知。這就是爲什麼數字簽名可以很好地處理各種二進制文檔等。
  • trim() javascript或strip()在Python中使用字符串,它們的行爲可能因底層編碼而異(例如,在python中嘗試u's '.encode('utf-16').strip().decode('utf-16'))。如果可能的話,我寧願避免使用修剪,以免混淆數據處理的方式。
  • Python 2.x(並且,我想,Javascript也是)爲字符串和原始數據之間的隱式轉換設置了一組規則。

在您的代碼中,您使用Python中的二進制數據,但在定義要讀取的文件的編碼時,在JavaScript中進行字符串轉換。顯然,在crypto模塊中有一種從utf-8轉換回原始字符串的隱式轉換,但我不知道它的作用。

here所述,在node.js中處理原始字符串的最奇妙方式是使用緩衝區。您可以從文件系統讀取緩衝區,但不幸的是,nodejs加密庫不支持它們。如所描述的here

的加密模塊被添加到節點之前有一個 統一流API的概念,和之前有緩衝對象處理 二進制數據。

因此,流類沒有在其他節點類上找到的典型方法,許多方法默認接受並返回二進制編碼的 字符串,而不是緩衝區。

這是說,爲了使示例工作,目前的做法是通過「二進制」作爲第二個參數來調用讀取數據:

file = fs.readFileSync argv.file, "binary" 

而且,正如我所說,我會而是避免剝離剛剛從文件中讀取的數據。

1

一些想法嘗試:

  • 檢查raw具有相同的長度爲file
  • 打開f二進制
  • import codecs和使用codecs.open與編碼
  • strip將刪除所有空白Python中字符串的開始和結尾 - 我認爲trim只能從結尾刪除。所以,你可能要設置爲獲得相同的行爲
+0

修剪從開始和結束中刪除以及 – mrwooster

+0

你可能會對某事,長度是不同的2個字符。這是不適用於帶/裝飾,不同的是2個字符沒有他們 – mrwooster

+0

@mrwooster只是縮小到如果相同的文件正在閱讀,那麼它可能是編碼 - 快樂狩獵... –