hmac.New(h func() hash.Hash, key byte) hash.Hash 在 JavaScript 中等效
在PHP中,我們經常需要使用加密演算法來保護資料的安全性。 HMAC(Hash-based Message Authentication Code)是一種常用的加密演算法,用於驗證資料完整性和身份認證。在PHP中,我們可以使用hmac.New()函數來建立HMAC實例,該函數需要指定一個雜湊函數和一個金鑰。與此類似,在JavaScript中,我們可以使用等效的方法來實現相同的功能。在本文中,我將為您介紹如何在JavaScript中使用等效的方法來建立HMAC實例,以及如何在PHP和JavaScript之間進行資料的加密和解密。
問題內容
差點在go lang hmac.new的js實作中卡住好幾天了。然而,沒有成功。我使用 crypto
、crypto-js
和 stablelib
模組進行實作。問題是,在go lang版本中,hmac
實例可以透過hmac
實例建立。例如(程式碼區塊正確且經過測試):
hmacf := hmac.New(func() hash.Hash { return hmac.New(func() hash.Hash { return hmac.New(func() hash.Hash { return hmac.New(sha256.New, []byte(SALT)) }, []byte(path[0])) }, []byte(path[1])) }, []byte(path[2]))
其實我也不知道它是怎麼運作的!因為在所有與 javascript 相關的模組中,您無法從 hmac
建立 hmac
,並且它們接受確定雜湊演算法的 string
值。
也許最好問如何在javascript中從hmac
建立hmac
。
解決方案是什麼?
當 go 版本的輸出與您的實作的輸出相同時;您的解決方案是正確的。
解決方法
根據規格 (rfc 2104),hmac 使用摘要函數內部,例如sha256。
但是,您的實作應用了(實際上不相容)內部使用另一個 hmac 而不是摘要的 hmac,其中只有最低等級的 hmac 在內部使用常規摘要。這樣就創建了一個嵌套結構。
基於常規 hmac(帶有摘要)的規範,這可以擴展到 go 程式碼中使用的帶有 hmac(而不是摘要)的 hmac:
hmac(k xor opad, hmac(k xor ipad, text))
s。 rfc2104,第 2 節。 hmac 的定義
由於與規範的差異,找到一個開箱即用的支援此類功能的 javascript 庫可能不會那麼容易。
雖然大多數函式庫當然支援hmac,但只允許指定摘要(而不是hmac),例如nodejs的crypto模組的crypto.createhmac()
,請參見還有其他答案。我認為這種方法不能用於實作 go 程式碼中的邏輯。
如果其他答案的方法不起作用,並且您找不到另一個具有所需功能的 javascript 庫,您可以自己在 javascript 中實現邏輯,因為 hmac 的規範相對簡單(見上文) )。
以下程式碼是 nodejs 的 crypto 模組的範例實作:
var crypto = require('crypto') const digest = 'sha256' const blocksize = 64 // block size of the digest // define input parameter var salt = buffer.from('salt') var path = [ buffer.from('alfa'), buffer.from('beta'), buffer.from('gamma') ] var data = buffer.from('data') // calculate hmac var hmac = hmac(data, salt, path) console.log(hmac.tostring('hex')) function hmac(data, salt, path) { // create keylist var keylist = [] keylist.push(salt) keylist = keylist.concat(path) // determine hmac recursively var result = hmac_rec(data, keylist) return result } function hmac_rec(data, keylist) { // adjust key (according to hmac specification) var key = keylist.pop() if (key.length > blocksize) { k = buffer.allocunsafe(blocksize).fill('\x00'); if (keylist.length > 0) { hmac_rec(key, [...keylist]).copy(k) } else { gethash(key).copy(k) } } else if (key.length < blocksize) { k = buffer.allocunsafe(blocksize).fill('\x00'); key.copy(k) } else { k = key } // create 'key xor ipad' and 'key xor opad' (according to hmac specification) var ik = buffer.allocunsafe(blocksize) var ok = buffer.allocunsafe(blocksize) k.copy(ik) k.copy(ok) for (var i = 0; i < ik.length; i++) { ik[i] = 0x36 ^ ik[i] ok[i] = 0x5c ^ ok[i] } // calculate hmac if (keylist.length > 0) { var innerhmac = hmac_rec(buffer.concat([ ik, data ]), [...keylist]) var outerhmac = hmac_rec(buffer.concat([ ok, innerhmac ]), [...keylist]) } else { var innerhmac = gethash(buffer.concat([ik, data])) var outerhmac = gethash(buffer.concat([ok, innerhmac])) } return outerhmac } // calculate sha256 hash function gethash(data){ var hash = crypto.createhash(digest); hash.update(data) return hash.digest() }
結果:
2e631dcb4289f8256861a833ed985fa945cd714ebe7c3bd4ed4b4072b107b073
測試:
以下 go 程式碼產生相同的結果:
package main import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" "hash" ) func main() { salt := "salt" path := []string{"alfa", "beta", "gamma"} hmacf := hmac.new(func() hash.hash { return hmac.new(func() hash.hash { return hmac.new(func() hash.hash { return hmac.new(sha256.new, []byte(salt)) }, []byte(path[0])) }, []byte(path[1])) }, []byte(path[2])) hmacf.write([]byte("data")) result := hmacf.sum(nil) fmt.println(hex.encodetostring(result)) // 2e631dcb4289f8256861a833ed985fa945cd714ebe7c3bd4ed4b4072b107b073 }
編輯:
受這篇文章的啟發,以下是hmac_rec()
的更緊湊/高效的實現,它使用常規最後一個迭代步驟的hmac(這也使得gethash()
過時):
function hmac_rec(data, keyList) { var key = keyList.pop() if (keyList.length > 0) { // adjust key (according to HMAC specification) if (key.length > blockSize) { k = Buffer.allocUnsafe(blockSize).fill('\x00'); hmac_rec(key, [...keyList]).copy(k) } else if (key.length < blockSize) { k = Buffer.allocUnsafe(blockSize).fill('\x00'); key.copy(k) } else { k = key } // create 'key xor ipad' and 'key xor opad' (according to HMAC specification) var ik = Buffer.allocUnsafe(blockSize) var ok = Buffer.allocUnsafe(blockSize) k.copy(ik) k.copy(ok) for (var i = 0; i < ik.length; i++) { ik[i] = 0x36 ^ ik[i] ok[i] = 0x5c ^ ok[i] } // calculate HMAC var innerHMac = hmac_rec(Buffer.concat([ ik, data ]), [...keyList]) var outerHMac = hmac_rec(Buffer.concat([ ok, innerHMac ]), [...keyList]) } else { var outerHMac = crypto.createHmac(digest, key).update(data).digest(); } return outerHMac }
以上是hmac.New(h func() hash.Hash, key byte) hash.Hash 在 JavaScript 中等效的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

自 2009 年問世以來,比特幣成為加密貨幣界的領頭羊,其價格經歷了巨大的波動。為了提供全面的歷史概述,本文匯集了從 2009 年到 2025 年的比特幣價格數據,涵蓋了重大的市場事件、市場情緒變化和影響價格走勢的重要因素。

比特币,作为一种加密货币,自问世以来经历了显著的市场波动。本文将提供比特币自诞生以来的历史价格总览,帮助读者了解其价格趋势和关键时刻。通过分析比特币的历史价格数据,我们可以了解市场对其价值评估、影响其波动的因素,并为未来投资决策提供依据。

比特幣自 2009 年創世以來,價格經歷多次大幅波動,最高漲至 2021 年 11 月的 69,044.77 美元,最低跌至 2018 年 12 月的 3,191.22 美元。截至 2024 年 12 月,最新價格突破 100,204 美元。

實時比特幣美元價格 影響比特幣價格的因素 預測比特幣未來價格的指標 以下是 2018-2024 年比特幣價格的一些關鍵信息:

CSS自定義resize符號的方法與背景色統一在日常開發中,我們經常會遇到需要自定義用戶界面細節的情況,比如調...

是的,H5頁面製作是前端開發的重要實現方式,涉及HTML、CSS和JavaScript等核心技術。開發者通過巧妙結合這些技術,例如使用<canvas>標籤繪製圖形或使用JavaScript控制交互行為,構建出動態且功能強大的H5頁面。

關於inline-block元素錯位顯示的原因及解決方案在編寫網頁佈局時,我們常常會遇到一些看似奇怪的顯示問題。比...
