Closed aluco100 closed 6 years ago
@aluco100 well, you shouldn't use exclamation marks in this library in case of unknown nullability modifier. ( It is intended to support iOS prior to 6 version, I don't know if anybody use it. So, we don't put any modern clang items into it for Xcode 5 compatibility. ) (I am not sure about this :))
In fact, correct usage in Swift:
func verify(parameters: [String: AnyObject]) -> Bool {
// retrieve items from params
let algorithm = JWTAlgorithmNameRS256
guard let holder = JWTAlgorithmRSFamilyDataHolder().verifyKey(publickey as? JWTCryptoKeyProtocol)?.algorithmName(algorithm)? else {
return false
}
guard let decoding: JWTDecodingBuilder = JWTDecodingBuilder.decodeMessage(user.access_token).addHolder(holder) as? JWTDecodingBuilder else {
return false
}
print(decoding.decode.successResult as Any)
print(decoding.decode.errorResult.error as Any)
return decoding.decode.successResult != nil // or check for errorResult is nil
}
Next, I can't see your key. Library has troubles in retrieving keys from files. Now library has troubles in retrieving keys from strings, according to your post.
Ok, assume, that you have correct key format in string. Please, open JWTCryptoKeySecurity.h and test your key against extraction function.
+ (NSString *)keyFromPemFileContent:(NSString *)content
and I suppose it has swift signature
class func key(fromPemFileContent: String!) -> String!
Your format should be either base64 without PEM headers or PEM-base64 with headers and new lines. ( As PEM-format has new lines alignment for long key strings )
My issue it's still occuring. My code is this:
let publickey = "-----BEGIN PUBLIC KEY-----(valid key)-----END PUBLIC KEY-----"
let crypto = JWTCryptoSecurity.key(fromPemFileContent: publickey)
let algorithm = JWTAlgorithmNameRS256
guard let holder = JWTAlgorithmRSFamilyDataHolder().verifyKey(crypto as? JWTCryptoKeyProtocol)?.algorithmName(algorithm) else {
reject(NSError(domain: "ahumada", code: 119, userInfo: nil))
return
}
guard let decoding: JWTDecodingBuilder = JWTDecodingBuilder.decodeMessage(user.access_token).addHolder(holder) as? JWTDecodingBuilder else{
reject(NSError(domain: "ahumada", code: 119, userInfo: nil))
return
}
print(decoding.decode.successResult as Any)
print(decoding.decode.errorResult.error as Any)
What can be happen?
Best Regards
@aluco100 Could you post output of extraction function ( in JWTCryptoSecurity )?
class func key(fromPemFileContent: String!) -> String!
As is:
let extractedKey = JWTCryptoKeySecurity.key(yourKey)
print("key is: \(extractedKey)")
@lolgear my output is:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoPryo3IisfK3a028bwgso/CW5kB84mk6Y7rO76FxJRTWnOAla0Uf0OpIID7go4Qck66yT4/uPpiOQIR0oW0plTekkDP75EG3d/2mtzhiCtELV4F1r9b/InCN5dYYK8USNkKXgjbeVyatdUvCtokz10/ibNZ9qikgKf58qXnn2anGvpE6ded5FOUEukOjr7KSAfD0KDNYWgZcG7HZBxn/3N7ND9D0ATu2vxlJsNGOkH6WL1EmObo/QygBXzuZm5o0N0W15EXpWVbl4Ye7xqPnvc1i2DTKxNUcyhXfDbLw1ee2d9T/WU5895Ko2bQ/O/zPwUSobM3m+fPMW8kp5914kwIDAQAB
Best Regards
@aluco100
try to set secretData to Data()
I suppose it is the same issue:
Well, I can use JWTCryptoSecurity.publicKey(fromCertificate: publickey.data(using: .utf8)!)
or anything else? @lolgear
Best Regards
try
guard let holder = JWTAlgorithmRSFamilyDataHolder()
.verifyKey(crypto as? JWTCryptoKeyProtocol)?
.secretData(Data())
.algorithmName(algorithm)
else {
reject(NSError(domain: "ahumada", code: 119, userInfo: nil))
return
}
I use this:
let crypto = JWTCryptoSecurity.key(fromPemFileContent: publickey)
let algorithm = JWTAlgorithmNameRS256
guard let holder = JWTAlgorithmRSFamilyDataHolder().signKey(crypto as? JWTCryptoKeyProtocol)?.verifyKey(crypto as? JWTCryptoKeyProtocol)?.secretData(Data())?.algorithmName(algorithm) else {
reject(NSError(domain: "ahumada", code: 119, userInfo: nil))
return
}
guard let decoding: JWTDecodingBuilder = JWTDecodingBuilder.decodeMessage(user.access_token).addHolder(holder) as? JWTDecodingBuilder else{
reject(NSError(domain: "ahumada", code: 119, userInfo: nil))
return
}
print(decoding.decode.successResult as Any)
print(decoding.decode.errorResult.error as Any)
As you said but I'm still getting the same issue. Any idea?
@aluco100 Could you attach sample swift project with fresh generated keys and test data?
Besides, try to encode and decode any data by the same holder that you posted above. ( If your data comes somewhere outside )
@aluco100 well... Short story is I need time to investigate your issue. Somehow in deep of CryptoKey your key is not properly formed. And after that I have found another issue related or not. I have found that base64 secrets are not well formed. ( So that's is why it is still in beta, heh )
Ok, so is it a base 64 bug?
Best Regards
@aluco100 I've solved this puzzle! :) I could post your project here and if you don't mind, I would like to post your token/secret as a part of JWTDesktop app. ( default setup for rs256 )
The core thing is to use JWTCryptoKeyPublic instead
of "abstract" JWTCryptoKey
.
It's Ok. Can you give me an example to use this?
Best Regards
@aluco100 Here it is SampleSignature.zip
Ok @lolgear that's works perfectly. Thanks a lot for your patience!
I still experience the same issue when encoding a JWT payload, then trying to verify it using an RSA keypair generated with OpenSSL and using RS256 as the algorithm. I use JWT 3.0.0-beta7 through Carthage and I have also tried below code in your SampleSignature project, both yielding the same results. As a starting point I have used the SampleSignature project you included in this thread. I have tried using different keypairs and I always get the same results. What's even more weird is that when I plug the encoded JWT token to jwt.io, it says the signature is verified. However, the JWT framework throws below error
Error Domain=io.jwt Code=-97 "Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header."
and the Box API also doesn't accept the JWT token, where I would actually use the JWT token for authentication.
The code I used for encoding the JWT payload and verifying can be found below along with the output it produces.
let publickey = """
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKk/ZQxuEsWosbTVEGDNRx5touAR2vdW
Y+3hnFbTrFl6KPHrKV3cax5jTMdrzLmV9b7vpAsdOYPKFukRgQIfhNUCAwEAAQ==
-----END PUBLIC KEY-----
"""
let privateKeyString = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAoZh3JTinfA2/9NmiDsirluyqsuefd6/etaCLQ9lZVPbvaZJN
RI+vFx8dy8/vVM4YC1Ig8GLbYAU/EBOvYSOuuqIDyGiG7CFWJEZfjz5yJ85SuB2h
7vLXnIhInHYwEhW/cmxRG9BIJGipsw9LvYWtDWk439RlLzqlz6iUP83a13x1JqYO
CTTKkH/LzQTBGjOyexF+0VDKeiBz/fp+xbwxc5nwSmqRQjVKh+/qqGaR8gguSzx9
oKaugGeytiYEDQoOZgk18w+ZdaPj6ChhoEN0WkSNona4Ab2VG4W8cKhmYxzEB4NY
mSXara8XScakjAw8EymOWCB53kS0vm60R1ILUwIDAQABAoIBACrwHkiPo0E9ThI7
eeo/vAhgXoMnNKJS4vST8i1XJXuEGd2NeGaNX1Lfe8VaPRflo1Huwr3dJrl+62DU
OjeviZAh2Kt5ytAXk5IT+PRQ/XhCRIyToyGg+VWoiNK6PM+xY6t9yJeBYon6HY1s
tQ1o5bC4kto2z6QbC1AAVVQW2N2E0mYSnJ6JdUos95NFA6C/qxbobOPuFjl6vP2o
jSu3nfn1WLuFybntBWsgoV8WA98yq/8qAltxDTB1XQznTGYpVUVPwjMKNPIK7iFQ
gOMlCJztBQ/CRg8hXCNEYLNS2GlAeyVJb2Luw1Q7QAZyzWHGA8RN9XFh7eZfzOM8
/BF9kqECgYEA0BdhNEXMQta6a1pVYcIY05vHqk4xGYCkwS2bkDrgN788ra7ILcqW
jKo1pX08jettjI3hqisLQE28d+VgT6xuYLitPuhxaQUOuXhq8ZLZxCpBJgp3i61+
J9WlxT16lPB+p5JsLTz6Oz4E+HcC2K3WqPZSxOkyi1N/lF3Qe9ZacgsCgYEAxsyw
VTQxHFOvTL7TnIhN+RcKgIGrMyRWLNMrs7Svq/GHlqAB7OyRm9ij8m/EY71bSHqN
39Dv82yF7SHqaHhl4bztTfDisfrNM+Z0V5/zpO1lBKzaMEcVmV29zSj0MeI2jYKT
ywFnxlHmzTV0NWlROA0VcgguETtFvXR+1GjyINkCgYA6CFsmfdSySzogGEg5hCzy
Tr6HQ1k0GIlaCoMY3SKMyXt9oIHZK2eDATEG3v9VQPQDP8pQb8Kqg0NtWH3cmmUJ
+lbudVqzhCKQHQIOLvsmVvZmSoL+ZDsLluytLjESemOIDjC3CQtsHCa8uEwF660y
38dDfRmIe5fX47Xx41zD8wKBgQCcz7K70sp2TLB3OgMTcxUGSZ14FlBjq+Lpwryz
KPB1EbThJF/Aci69Htrbjjv8bM4HUtx8UoQjoFPX5CvRsj6zHGKXW06GE44vxTW6
NKpsSvGnCW2mLTwlWKMxpH9SpdxgLULFG9uuvMXw0pxS0TtGmlNzOm6UGwv80FqG
1C1BqQKBgQCWchFf5m90GUGJRVAi4akyYnOKnoQdLbku6sD41le0vSSvN9cs5x2C
e+9vTop0bd1f3N1nzMb1ElZUF50orqoRpkxMp3mEqjZS0qy6WG3NtOB+WrcIiKhL
J2FS/hfBlZfefhuYokJwddiOZtINMnYD3SqoiQjF3ta5jMv7EYbArA==
-----END RSA PRIVATE KEY-----
"""
let payload:[String:Any] = ["iss":"gadsarewrhg12klkj","sub":"43","aud":"https://api.box.com/oauth2/token","exp":Int(Date().addingTimeInterval(59).timeIntervalSince1970),"jti":UUID().uuidString,"box_sub_type": "enterprise"]
let headers = ["alg":"RS256","typ":"jwt","kid":"rewrew21"]
override func viewDidLoad() {
super.viewDidLoad()
var crypto: JWTCryptoKeyProtocol? = nil
do {
crypto = try JWTCryptoKeyPublic(pemEncoded: publickey, parameters: nil)
}
catch {
NSLog("error: \(error)")
}
guard let theCrypto = crypto else {
return
}
do {
let privateKey = try JWTCryptoKeyPrivate(pemEncoded: privateKeyString, parameters: nil)
guard let holder = JWTAlgorithmRSFamilyDataHolder().signKey(privateKey)?.secretData(privateKeyString.data(using: .utf8)!)?.algorithmName(JWTAlgorithmNameRS256) else {return}
guard let encoding = JWTEncodingBuilder.encodePayload(payload).headers(headers)?.addHolder(holder) else {return}
let result = encoding.result
print(result?.successResult?.encoded ?? "Encoding failed")
print(result?.errorResult?.error ?? "No encoding error")
let verifyDataHolder = JWTAlgorithmRSFamilyDataHolder().signKey(theCrypto)?.secretData(publickey.data(using: .utf8)!)?.algorithmName(JWTAlgorithmNameRS256)
let verifyResult = JWTDecodingBuilder.decodeMessage(result?.successResult?.encoded).addHolder(verifyDataHolder)?.result
if verifyResult?.successResult != nil, let result = verifyResult?.successResult.encoded {
print("Verification successful, result: \(result)")
} else {
print("Verification error: \(verifyResult!.errorResult.error)")
}
} catch {
print(error)
}
}
Output:
eyJhbGciOiJSUzI1NiIsInR5cCI6Imp3dCIsImtpZCI6InYwb2xjbnA2In0.eyJleHAiOjE1MTYxMjIxOTcsImp0aSI6IjIzQjFBNUM3LUQwMjctNDNGNC1BRjkxLTAzNDQ0OUQyRjY2RCIsImlzcyI6ImZyMjNocjdxNWZ1dHV0bGI3MDI4a2M3ZWNxYmV1eXd1IiwiYm94X3N1Yl90eXBlIjoiZW50ZXJwcmlzZSIsImF1ZCI6Imh0dHBzOlwvXC9hcGkuYm94LmNvbVwvb2F1dGgyXC90b2tlbiIsInN1YiI6IjM3MjQ4Njc0In0.g1e4Lu-uf_1opcmP7gbpAkH0LmatiVLS7PgiCHFaACerEZsAS488k4qTD9twi4Ei-dojGvT2exgw-aVjxkj0qk92BXpkN4n4ZSTUqs_qoYiJeX2jytGs0kO-OIhR267hkzphcBh5VHXg4OwI5_6oq-hP3DA6gQRYdSDZtJ2YVlS26bpRURSUq28-4TfX8iaqiiia_0oO2UvtvJanLhSrrVEW5IUabygxVBWYiQhgrVu11L_MzrHPtx3JF_e1n7--SE_tzQ19EBPrOdGt3OHYxmr8scmz3tzgPyfbS61izIlTfCvD0Oe900GnSzdaVUB46t_NJM8uk249moA0sYsHnA No encoding error Verification error: Optional(Error Domain=io.jwt Code=-97 "Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header." UserInfo={NSLocalizedDescription=Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header., errorDescription=JWTInvalidSignatureError})
@lolgear Do you have any idea what might go wrong?
@davidpasztor
let verifyDataHolder = JWTAlgorithmRSFamilyDataHolder().signKey(theCrypto)?.secretData(publickey.data(using: .utf8)!)?.algorithmName(JWTAlgorithmNameRS256)
try to set verifyKey
to publicKey and set secretData(Data())
to empty data. (cheats, yes)
let publicKey = JWTCryptoKeyPublic(pemEncoded: publicKeyString, parameters: nil)
Also, check the length of the RSA key. ( Or try to use this key in Objective-C JWTDesktop application to exclude possible crypto-related issues with keys. )
@lolgear sadly setting verifyKey
to publicKey
and secretData(Data())
doesn't help either.
let verifyDataHolder = JWTAlgorithmRSFamilyDataHolder().signKey(publicKey)?.verifyKey(publicKey)?.secretData(Data())?.algorithmName(JWTAlgorithmNameRS256)
produces the same error as before.
What should be the length of the RSA key that I should check for?
Sadly the Obj-C JWTDesktop application also yields above error.
@lolgear Finally managed to solve the issue. It was caused by the lack of the Base64 framework. After importing it to my project, everything started working. However, I have a question and a request about this. Firstly, how can the JWT framework work at all without importing the Base64 framework if that framework is a hard dependency on JWT? Secondly, for the request, it would be appreciated if you could change the readme file and include in the Carthage installation instructions the need for Base64 as a dependency.
@davidpasztor
in Base64Coder:
#if __has_include(<Base64/MF_Base64Additions.h>)
#import <Base64/MF_Base64Additions.h>
#elif __has_include("MF_Base64Additions.h")
#import "MF_Base64Additions.h"
#endif
Also, it has various respondsToSelector
to guard unknown selectors invocation ( which are present in Base64 framework )
Yes, Base64 framework has more accurate implementation of Base64 algorithm ( with additional features of base64 url encoding sanitizers ), here could be a hidden problem.
@lolgear
I tried both way to decode on objective C for iOS
id <JWTCryptoKeyProtocol> publicKey = [[JWTCryptoKeyPublic alloc]
initWithPemEncoded:publickey_ parameters:nil error:nil];
id <JWTAlgorithmDataHolderProtocol> holder = [JWTAlgorithmRSFamilyDataHolder new].verifyKey(publicKey).algorithmName(JWTAlgorithmNameRS256);
JWTCodingBuilder *verifyBuilder = [JWTDecodingBuilder decodeMessage:token].addHolder(holder);
JWTCodingResultType *verifyResult = verifyBuilder.result;
if (verifyResult.successResult){
NSLog(@"%@ success: %@", self.debugDescription, verifyResult.successResult.payload);
token = verifyResult.successResult.encoded;
}
else
{
NSLog(@"%@ error: %@", self.debugDescription, verifyResult.errorResult.error);
}`
Also this one too which given in example
NSString *algorithmName = @"RS256";
JWTBuilder *decodeBuilder = [JWTBuilder decodeMessage:token].secret(publickey_).algorithmName(algorithmName);
NSDictionary *envelopedPayload = decodeBuilder.decode;
Both cases I got same error while doing decoding
Key and Token I used same what you had used Here
Domain=io.jwt Code=-97 "Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header."
Can you please guide me what I need to do for make it working ? Thank you
Hi, I'm using a valid RS256's secret for an access token, but I have an invalid signature by the
JWTDecodingBuilder
. I write the following code in swift:And I get back this error:
Error Domain=io.jwt Code=-97 "Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header." UserInfo={NSLocalizedDescription=Invalid signature! It seems that signed part of jwt mismatch generated part by algorithm provided in header., errorDescription=JWTInvalidSignatureError}
I'm using xCode 9 with the last pod version (3.0.0-beta.5). So, what am I doing wrong?
Best Regards