gpt4 book ai didi

ios - HMAC SHA256 JWT 签名不正确

转载 作者:可可西里 更新时间:2023-11-01 00:59:10 25 4
gpt4 key购买 nike

答案:

下面的 hmac func 是我现在使用的函数...

func base64Encoded(algorithm: CryptoAlgorithm, key: String) -> String {
let hmac = self.hmac(algorithm: algorithm, key: key)
let digestLen = algorithm.digestLength
let dataResult = NSData(bytes: hmac, length: digestLen)
hmac.deallocateCapacity(digestLen)

return dataResult.base64EncodedString()
}

func hash(algorithm: CryptoAlgorithm, key: String) -> String {
let hmac = self.hmac(algorithm: algorithm, key: key)
let digestLen = algorithm.digestLength
let hash = NSMutableString()

for i in 0..<digestLen {
hash.appendFormat("%02x", hmac[i])
}

hmac.deallocateCapacity(digestLen)

return hash as String
}

func hmac(algorithm: CryptoAlgorithm, key: String) -> UnsafeMutablePointer<CUnsignedChar> {
let str = self.cString(using: String.Encoding.utf8)
let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = algorithm.digestLength

let result = UnsafeMutablePointer<CUnsignedChar>(allocatingCapacity: digestLen)

let keyStr = key.cString(using: String.Encoding.utf8)
let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))

CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)

return result
}

原帖

我有一个 JWT,我正在尝试验证签名。这是 JWT...

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhcGkudGVzdC5jb20vdjEvYXV0aCIsImV4cCI6MTQ2OTk3ODQ5OCwic3ViIjoiMTIzNDU2Nzg5MCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsInJvbGVzIjpbImFkbWluIiwiY3VzdG9tZXIiXSwicGVybWlzc2lvbnMiOlsidGVzdC5wcm9maWxlIiwidGVzdC5wcm9maWxlLmNvbnRhY3QiLCJ0ZXN0LnByb2ZpbGUuZGV2aWNlIiwidGVzdC5wcm9maWxlLmFwcCJdfQ.GfLxXOL978Pm5GYMI0WTBEVcMrfVj2jJb-Il_XzO7g4

我在 Swift 3 中工作,我更新了这个 SO 答案中的方法 https://stackoverflow.com/a/24411522/741626 .这就是这些方法现在的样子。

import Foundation

enum CryptoAlgorithm {
case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

var HMACAlgorithm: CCHmacAlgorithm {
var result: Int = 0
switch self {
case .MD5: result = kCCHmacAlgMD5
case .SHA1: result = kCCHmacAlgSHA1
case .SHA224: result = kCCHmacAlgSHA224
case .SHA256: result = kCCHmacAlgSHA256
case .SHA384: result = kCCHmacAlgSHA384
case .SHA512: result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}

var digestLength: Int {
var result: Int32 = 0
switch self {
case .MD5: result = CC_MD5_DIGEST_LENGTH
case .SHA1: result = CC_SHA1_DIGEST_LENGTH
case .SHA224: result = CC_SHA224_DIGEST_LENGTH
case .SHA256: result = CC_SHA256_DIGEST_LENGTH
case .SHA384: result = CC_SHA384_DIGEST_LENGTH
case .SHA512: result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}

extension String {

func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = algorithm.digestLength

let result = UnsafeMutablePointer<CUnsignedChar>(allocatingCapacity: digestLen)

let keyStr = key.cString(using: String.Encoding.utf8)
let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))

CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)

let hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}

result.deallocateCapacity(digestLen)

return hash as String

}

我能够成功地对 header 和有效负载进行 base64 解码,但是当我尝试验证签名时,它总是错误的(看起来一点也不像,而且太长了)。

我尝试过的。

1 我已经尝试了几个 JWT - 总是以同样的方式出错

2 我已经对 sha256 常量进行硬编码以确保我没有使用错误的编码/长度

3 我已经尝试了多种类型的 String.Encoding,但尽管它们总是生成与预期不同的结果,但它们都没有生成所需的签名。

4 我已经使用 Objective-C 方法生成 hmac 来尝试排除我转换到 Swift 3 时是否出现任何问题。结果相同,这是 Objective C 代码。

+ (NSData *)hmacSha256:(NSString *)string key:(NSString *)key;
{
NSData *dataIn = [string dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyIn = [key dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];

CCHmac( kCCHmacAlgSHA256,
keyIn.bytes,
keyIn.length,
dataIn.bytes,
dataIn.length,
macOut.mutableBytes);

return macOut;
}

代码源自此处:https://stackoverflow.com/a/31003443/741626 .我宁愿不将 Objective-C 代码插入到我的 Swift 项目中,但如果必须的话,我会的!

这是我的调用函数

func decodeToken(token: String) {
let array = token.characters.split(isSeparator: { $0 == "." })
.map(String.init)

let header:String = String(array[0])
let payload:String = String(array[1])
let signature:String = String(array[2])

let encodedString = header + "." + payload
let hmac = encodedString.hmac(algorithm: .SHA256, key: "")
}

编辑

当我运行代码时,生成的 hmac 是

19f2f15ce2fdefc3e6e4660c23459304455c32b7d58f68c96fe225fd7cceee0e

我已经三次检查密码是否正确,即""(空字符串)

我做错了什么?

我真的很想在我的客户端应用程序中测试我收到的 token 是否值得信赖,而不是掩饰这一点。如果有人知道我做错了什么,那就太好了。

最佳答案

实际上,您生成的值是正确的。只是您正在查看 HMAC 值的十六进制表示(以及哈希函数),而 JWT 哈希当然是 base64url 编码的。

要验证散列,比较字节值而不是编码值很重要。编码值仅供人类使用(十六进制)或通过需要文本的协议(protocol)(base64url)传输。


进行字节数组比较时,请确保它是时间常数,否则可能会引入漏洞。

一种方法是对字节进行异或运算,然后将结果或运算结果放入一个结果字节中。然后根据 00h 测试该结果字节(任何其他值表示无效比较)。首先拒绝大小不正确的数组。

关于ios - HMAC SHA256 JWT 签名不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38199889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com