【问题标题】:Swift HMAC doesn't match NodeJS HMAC, but only sometimes!Swift HMAC 不匹配 NodeJS HMAC,但只是有时!
【发布时间】:2019-09-24 21:31:24
【问题描述】:

我在我的代码中发现了一个巨大的问题,我根本不知道是什么原因造成的。

所以,当我向服务器发送请求时,我会对请求中的字符串进行哈希处理。这有时是用户输入。

我的应用程序是多语言的,所以我必须支持所有“ä”字符等。

所以对于普通的英文字母/字符数字等,这种散列方法就像做梦一样。但是当被散列和比较的字符串包含“ä”或“ö”时(不是特别是那些,实际上可能是任何不在 Base64 集中的字符都会导致这种情况)散列不匹配!

这绝对是一场彻头彻尾的灾难,到目前为止我还没有注意到它。我基本上已经尝试了我所知道的一切来尝试解决这个问题,并在谷歌上搜索,但到目前为止我很不走运。

我在 Swift 中生成哈希,将字符串和 secretToken 输入到这个函数中,并将输出保存为 HTTP 标头:

func hmac(string: String, key: String) -> String {

    var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))

    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), key, key.count, string, string.count, &digest)

    let data = Data(digest)

    return data.map { String(format: "%02hhx", $0) }.joined()

}

我如何比较 NodeJS 中的哈希:

if (hashInTheRequest === crypto.createHmac('sha256', secretToken).update(stringToHash).digest('hex')) {
    //Good to go
}

提前致谢!

【问题讨论】:

  • 字符是否有可能被编码两次或 URL 编码? %FC 而不是 ü,也许吧?
  • @BernhardDöbler 我在 http 数据中以 JSON 值发送字符串。所以这应该是不可能的。

标签: hash ios hmac node.js


【解决方案1】:

这可能是由于构图问题。您提到了非拉丁字符,但没有具体说明您遇到问题的具体示例。

什么是合成?

Unicode 旨在能够表示人类使用的任何字符。但是,许多字符是相似的,例如uüûū。最初的想法是只为每个可能的组合分配一个代码点。正如人们可能想象的那样,这不是存储东西的最有效方式。而是使用“基础”字符,然后添加一个组合字符。

我们来看一个例子:ü

ü可以表示为U+00FC,也称为LATIN SMALL LETTER U WITH DIAERESIS

ü也可以表示为U+0075u),后接U+0308◌̈),也称为LATIN SMALL LETTER U,后接COMBINING DIARESIS

为什么会有问题?

因为哈希函数不知道字符串是什么。他们关心的只是字节。因此,必须将字符串解码为字节串。如上所示,解码字符串有多种不同的方式,这意味着两个不同的系统可以将同一个逻辑字符串解码为不同的字节,从而产生不同的哈希值。

我该如何解决这个问题?

您必须明确定义字符串在两个平台上的解码方式,以确保两者以完全相同的方式解码字符串。

【讨论】:

    猜你喜欢
    • 2020-10-18
    • 2021-05-26
    • 2014-07-30
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 2015-09-07
    • 2014-08-23
    • 2017-08-16
    相关资源
    最近更新 更多