我在iOS中使用EC算法验证JWT时遇到问题。我使用ES 384算法从www.example.com生成了JWT和公钥jwt.io,我有以下验证器:
let jwtToken = "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.VUPWQZuClnkFbaEKCsPy7CZVMh5wxbCSpaAWFLpnTe9J0--PzHNeTFNXCrVHysAa3eFbuzD8_bLSsgTKC8SzHxRVSj5eN86vBPo_1fNfE7SHTYhWowjY4E_wuiC13yoj"
let publicKey = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEC1uWSXj2czCDwMTLWV5BFmwxdM6PX9p+Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii1D3jaW6pmGVJFhodzC31cy5sfOYotrzF"
let isValid = JWTValidator.validateSignature(forToken: jwtToken, withPublicKey: publicKey)
print(isValid) // always false
import ASN1Decoder
class JWTValidator {
static func validateSignature(forToken token: String, withPublicKey publicKeyText: String) -> Bool {
let parts = token.components(separatedBy: ".")
let header = parts[0]
let payload = parts[1]
let signature = parts[2]
guard let dataPublicKey = Data(base64Encoded: publicKeyText),
let dataSigned = (header + "." + payload).data(using: .ascii),
let dataSignature = Data(base64Encoded: base64StringWithPadding(base64str: signature)) else {
print("Failed to get signature!")
return false
}
var secKeyCreateError : Unmanaged<CFError>?
guard let publicKey: SecKey = DerDecoder().decodePublicKey(dataPublicKey,&secKeyCreateError) else {
print("Failed to create SecKey : %@", secKeyCreateError!.takeRetainedValue().localizedDescription)
return false
}
var validateError : Unmanaged<CFError>?
let algorithm: SecKeyAlgorithm = .ecdsaSignatureMessageX962SHA384
let result = SecKeyVerifySignature(peerPublicKey,
algorithm,
dataSigned as NSData,
dataSignature as NSData,
&validateError)
if let validateError = validateError {
print(validateError)
}
return result
}
static func base64StringWithPadding(base64str: String) -> String {
var newStr = base64str.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
let count = newStr.count % 4
if count > 0 {
let amount = 4 - count
for _ in 0..<amount {
newStr += "="
}
}
return newStr
}
}
class DerDecoder {
func decodePublicKey(_ data: Data, _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> SecKey? {
guard
let asn1 = try? ASN1DERDecoder.decode(data: data),
let keyData = asn1.first?.sub(1)?.value as? Data
else {
return nil
}
return SecKeyCreateWithData(
keyData as CFData,
[
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
] as CFDictionary,
error
)
}
}
最初我在获取SecKey时遇到了一些麻烦,但ASN 1Decoder解决了这个问题。现在我正在努力验证它。我总是得到false
。我不知道该使用什么SecKeyAlgorithm
。
这些是我得到的错误:
EC签名验证失败(ccerr -7)
或
密钥〈SecKeyRef曲线类型不支持算法:kSecECCurveSecp 384 r1,算法id:3、按键类型:ECPublicKey,版本:4、区块大小:384位,y:B2F393DFD51470F2513920F516A60BB9E774AD78A8A088A2D43DE3696EA9986549161A1DCC2DF5732E6C7CE628B6BCC5,x:0 B5 B 964978 F6733083 C 0 C4 CB 595 E41166 C3174 CE 8 F5 FDA 7 E3 E4 F587 FDAC 87 F7 EF 89 B 95 CFD 54 F2 AEFD 74184 B488 B 9AA 23,地址:0x102e26140〉
如果我使用www.example.com上的RS 256算法jwt.io,而不使用ASN 1Decoder和
let algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA256
完全没有问题。
任何帮助都将不胜感激。
1条答案
按热度按时间whlutmcx1#
对于那些正在努力解决Apple关于该主题的缺失文档的人来说-这是Apple开发者论坛中建议的工作示例:
所以我的代码中的问题是: