- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
答案:
下面的 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/
我得到了这个printHashKey函数,它运行良好。 fun printHashKey() { try { val info : PackageInfo = packageM
如何使用正确的签名 key 为我的 Android 应用包签名? 最佳答案 我尝试在此处和 this question 中使用多个答案, 但不知何故我收到了这个错误,因为我的 android/app/
我的 gradle 文件中有这个: android { signingConfigs { mySigningConfig { keyAlias 'the
请至少选择一个签名版本以在 Android Studio 2.3 中使用 现在在 Android Studio 中生成一个签名的 APK 时,它显示了两个选项(复选框),即 1. V1(Jar 签名)
我想表示一些标量值(例如整数或字符串)通过它的实际值或一些 NA 值,然后存储它们在集合中(例如列表)。目的是处理缺失值。 为此,我实现了一个签名 module type Scalar = sig
为什么这不完全有效? sum :: (Num a, Num b) => a -> b -> c sum a b = a + b 当然,错误消息与签名有关,但我仍然不明白原因。 Couldn't mat
谢谢帮助,我的问题是关于从下面的代码中收到的 ax 值? mov al,22h mov cl,0fdh imul cl 真机结果:ff9a 我的预期:00:9a(通过二进制相乘) 第一个数字是 22h
我有一个注释: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.
我从对物体的思考中得出了一个术语。当我们扩展一个类时,扩展类将具有与父类相同的签名,因此术语 IS-A 来自...示例 class Foo{ } class Foo2 extends Foo{ } c
我需要在有符号整数和它们作为字节序列的内部表示之间进行转换。在 C 中,我使用的函数如下: unsigned char hibyte(unsigned short i) {return i>>8;}
我正在尝试使用给定的 RSA 参数对一些数据进行签名。 我给出了模数、指数、D、DP、DQ、P、Q 和 InverseQ。什么库或方法最容易使用来计算此签名。在 C# 中,一旦您提供参数,它们就会有一
这些签名之间有什么区别? T * f(T & identifier); T & f(T & identifier); T f(T & identifier); void f(T * identifie
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Where and why do I have to put the “template” and “typ
我有一个签名,我需要在签名旁边添加图片。但我不确定 css 的确切程度和内容。目前它显示在文字下方,我应该把图片放在哪里?在相同的 tr 或 td 中?
查看 LinkedHashMap 的 JDK 源代码,我注意到这个类被声明为: public class LinkedHashMap extends HashMap im
背景:我继承了一个基于 linux 的嵌入式系统,其中包含一个 SMTP 代理和一些我不得不忍受的古怪限制。它位于 SMTP 客户端和服务器之间。当 SMTP 客户端连接时,代理会打开与服务器的连接,
这是 C++17 形式的规则 ([basic.lval]/8),但它在其他标准中看起来很相似(在 C++98 中是“lvalue”而不是“glvalue”): 8 If a program attem
我有一个注释: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.
我即将开展一个项目,希望使用电子签名板使用 C# 捕获客户的签名、在设备上显示文本等。 现在,在我开始做进一步的研究之前,我想向你们征求一些意见/建议,我应该使用哪些设备.. 我现在的要求非常笼统:我
呢喃自己在心中开始扩张地盘,仿佛制式地广播了三次。 漾起的涟绮,用谈不上精腻的手段。 拒绝天亮,却又贪恋着贪恋多情的日光。 川流不息的画面是他们,而我的落幕停在右脚,它渴望着下台,而我只剩自言
我是一名优秀的程序员,十分优秀!