2015-05-13 71 views
2

我想在node.js文件上執行RSA-SHA512。我可以計算與openssl相匹配的給定數據文件的sha512哈希值。 但是,當試圖在同一個散列上獲取數字簽名時,node.js簽名與openssl簽名不同。 下面是一個例子的代碼片斷:node.js加密簽名和openssl簽名不匹配

var data = new Buffer(512); 
data = fs.readFileSync('/tmp/data'); 
var pem = fs.readFileSync('/tmp/boot2-prvKey.pem'); 
var privateKey = pem.toString('ascii'); 

var signer = crypto.createSign("RSA-SHA256"); 
signer.update(data); 
var sign = signer.sign(privateKey, 'hex'); 
console.log("SIGN " + sign + '\n'); 

Openssl的命令對數據進行簽名:

openssl rsautl -sign -in /tmp/data -inkey /tmp/boot2-prvKey.pem -out sig 

的上述生成不同的簽名兩者。

我有幾個問題 1)我想計算一個文件的RSA-SHA256,所以我首先計算整個文件的sha256哈希,並將這個哈希值作爲輸入傳遞給簽名函數。 這是一個正確的方法嗎? 2)如果是,上面的代碼中可能出現了什麼問題?如果不是,那麼正確的方法是什麼?

我使用的node.js版本是0.10.36,而openssl版本是1.0,1。

+0

「*我首先計算整個文件的sha256哈希,並將此哈希作爲輸入傳遞給簽名函數*」 - 我沒有在您提供的代碼中使用哈希函數。這不是你真正的代碼,還是我誤解你的描述? – apsillers

+0

其實我有我的數據文件散列存儲在/ tmp/data,這是我在閱讀上面的代碼簽名。 對不起,不適用的文件命名。 –

回答

3

當您向簽名程序提供輸入時,它可能會假定輸入尚未散列,並且在簽名前將其散列。這裏的問題是節點(重新)散列輸入,而rsautl正在使用輸入。 (請注意,即使你單獨將其提供給rsautl前重新散列輸入,它仍然無法匹配,因爲rsautl不使用ASN1編碼;見下文)

爲了使OpenSSL的產生SHA256哈希製造前RSA簽名(如Node一樣),你需要使用dgst命令與-sha256-sign參數:

openssl dgst -sha256 -sign /tmp/boot2-prvKey.pem -hex < /tmp/data 

這將哈希/tmp/data並簽署與RSA的哈希,這是節點的RSA-SHA256簽名者究竟是幹什麼的。

有關更多信息,請參見Difference between openSSL rsautl and dgst

簡單的答案是,dgst -sign創建一個哈希,ASN1編碼,然後簽署ASN1編碼的哈希值,而rsautl -sign剛剛簽署輸入而不散列或ASN1編碼。

節點的sign方法的行爲就像是dgst -sign而非rsautl -sign

節點似乎沒有提供類似於內置rsautl的簽名機制,而不使用散列和ASN1編碼。出於這個原因,您可能需要直接簽署文檔,而不是使用文檔的散列。如果您出於某種原因確實無法完成此任務,則可以下載Node rsautl module from NPM,它爲rsautl提供節點綁定。

+0

但是從評論中看到這一點:*「...實際上我有我的數據文件散列存儲在/tmp/data..."*。所以看起來他已經有了哈希。我認爲他需要將簽名函數應用於哈希。或者他需要允許OpenSSL命令完成這一切(如上面所示)。如果他正在簽名,那麼簽署*未知*哈希或*未知*文件可能是危險的。我認爲這同樣適用於驗證,但不像簽署散列那樣糟糕。它應該是對文檔的原子操作,而不是分立部分的離散操作。 – jww

0

問題是您的Openssl命令只是簽署了您的數據而沒有散列函數。 必須首先散列與OpenSSL和具有相同的功能,在你的NodeJS代碼的數據(SHA-256)再簽收哈希在命令中獲得最終簽名: openssl rsautl -sign -in /tmp/data -inkey /tmp/boot2-prvKey.pem -out sig

你可以看到,在這個命令你沒有指定任何散列函數。

要獲得簽名:數據 - > SHA-256散列= - > RSA簽名=

我還沒有足夠的時間來測試它,給你正確的代碼,我希望這將是有益的。

+0

嗨保羅,感謝您的回覆。 我確實計算了我的數據文件的哈希值。哈希存儲在/ tmp/data中。 用openssl和node.js計算的哈希(sha256)完全匹配,因此我跳過代碼中的那部分,而只有給定哈希上的符號不同。因此,我明確表示兩種情況都只有簽署部分。 –