以节点兼容的方式编码 md5
Encoding md5 in a node compatible way
我正在转换节点服务。为此,我需要一个兼容的 md5 哈希(不用于存储密码!!)生成器。然而,在这个例子中,我不断得到不同的结果:
节点的 crypto
在创建 md5
时采用编码参数。
> crypto.createHash("md5").update("1Editor’s notebook: Escaping temptation for turf145468066").digest("hex")
'c7c3210bd977b049f42c487b8c6d0463'
在 golang 中:(test_encode.go)
package main
import (
"crypto/md5"
"encoding/hex"
"testing"
)
func TestFoo(t *testing.T) {
const result = "c7c3210bd977b049f42c487b8c6d0463"
stringToEncode := "1Editor’s notebook: Escaping temptation for turf145468066"
hash := md5.Sum([]byte(stringToEncode))
hashStr := hex.EncodeToString(hash[:])
if hashStr != result {
t.Error("Got", hashStr, "expected", result)
}
}
然后 go test test_encode.go
结果:
--- FAIL: TestFoo (0.00s)
encode_test.go:17: Got c3804ddcc59fabc09f0ce2418b3a8335 expected c7c3210bd977b049f42c487b8c6d0463
FAIL
FAIL command-line-arguments 0.006s
我已经追踪到节点代码中 crypto.update
的 encoding
参数。而事实上这个字符串作为一个’
引号字符在里面。如果我指定 "utf8"
它有效。
crypto.createHash("md5").update("1Editor’s notebook: Escaping temptation for turf145468066", "utf8").digest("hex")
但是:我无法更改节点代码,因此 go 代码必须兼容。有什么想法吗?
正如您已经注意到的:您必须将 UTF8 字符串转换为节点应用程序中使用的任何编码。这可以通过编码包来完成,例如:
golang.org/x/text/encoding/charmap
isoString, err := charmap.ISO8859_1.NewEncoder().Bytes([]byte(stringToEncode))
考虑到字符 ’
在 iso-8859-1 中是不允许的,我们可以假设您有不同的编码。现在你只需要弄清楚是哪一个!
在更糟糕的情况下,您可能不得不使用 charmap
之外的其他软件包。
在深入研究 node 和 V8 之后,我得出以下结论:
require("crypto").createHash("md5").update(inputString).digest("hex");
非常危险,因为不指定 a 会将输入字符串编码为 "ASCII"。经过大量挖掘后,这是等效的(从我这端在一个大输入集上验证):
// toNodeASCIIString converts a string to a byte of node compatible ASCII string
func toNodeASCIIString(inputString string) []byte {
lengthOfString := utf8.RuneCountInString(string(inputString))
stringAsRunes := []rune(inputString)
bytes := make([]byte, lengthOfString)
for i, r := range stringAsRunes {
bytes[i] = byte(r % 256)
}
return bytes
}
基本上做的是修改 256 并忘记输入字符串的很大一部分。
上面的节点示例几乎是在节点中创建 MD5 哈希值的标准复制粘贴方法。我没有检查过,但我假设这对所有其他哈希(SHA1、SHA256 等)都适用。
我很想听听大家的想法,为什么这不是一个巨大的安全漏洞。
我正在转换节点服务。为此,我需要一个兼容的 md5 哈希(不用于存储密码!!)生成器。然而,在这个例子中,我不断得到不同的结果:
节点的 crypto
在创建 md5
时采用编码参数。
> crypto.createHash("md5").update("1Editor’s notebook: Escaping temptation for turf145468066").digest("hex")
'c7c3210bd977b049f42c487b8c6d0463'
在 golang 中:(test_encode.go)
package main
import (
"crypto/md5"
"encoding/hex"
"testing"
)
func TestFoo(t *testing.T) {
const result = "c7c3210bd977b049f42c487b8c6d0463"
stringToEncode := "1Editor’s notebook: Escaping temptation for turf145468066"
hash := md5.Sum([]byte(stringToEncode))
hashStr := hex.EncodeToString(hash[:])
if hashStr != result {
t.Error("Got", hashStr, "expected", result)
}
}
然后 go test test_encode.go
结果:
--- FAIL: TestFoo (0.00s)
encode_test.go:17: Got c3804ddcc59fabc09f0ce2418b3a8335 expected c7c3210bd977b049f42c487b8c6d0463
FAIL
FAIL command-line-arguments 0.006s
我已经追踪到节点代码中 crypto.update
的 encoding
参数。而事实上这个字符串作为一个’
引号字符在里面。如果我指定 "utf8"
它有效。
crypto.createHash("md5").update("1Editor’s notebook: Escaping temptation for turf145468066", "utf8").digest("hex")
但是:我无法更改节点代码,因此 go 代码必须兼容。有什么想法吗?
正如您已经注意到的:您必须将 UTF8 字符串转换为节点应用程序中使用的任何编码。这可以通过编码包来完成,例如:
golang.org/x/text/encoding/charmap
isoString, err := charmap.ISO8859_1.NewEncoder().Bytes([]byte(stringToEncode))
考虑到字符 ’
在 iso-8859-1 中是不允许的,我们可以假设您有不同的编码。现在你只需要弄清楚是哪一个!
在更糟糕的情况下,您可能不得不使用 charmap
之外的其他软件包。
在深入研究 node 和 V8 之后,我得出以下结论:
require("crypto").createHash("md5").update(inputString).digest("hex");
非常危险,因为不指定 a 会将输入字符串编码为 "ASCII"。经过大量挖掘后,这是等效的(从我这端在一个大输入集上验证):
// toNodeASCIIString converts a string to a byte of node compatible ASCII string
func toNodeASCIIString(inputString string) []byte {
lengthOfString := utf8.RuneCountInString(string(inputString))
stringAsRunes := []rune(inputString)
bytes := make([]byte, lengthOfString)
for i, r := range stringAsRunes {
bytes[i] = byte(r % 256)
}
return bytes
}
基本上做的是修改 256 并忘记输入字符串的很大一部分。
上面的节点示例几乎是在节点中创建 MD5 哈希值的标准复制粘贴方法。我没有检查过,但我假设这对所有其他哈希(SHA1、SHA256 等)都适用。
我很想听听大家的想法,为什么这不是一个巨大的安全漏洞。