Verify signature of JWT token using iOS swift4
Often, JWT libraries provide functionality to verify a JWT's signature.
Anyway, in case you want to do it yourself: The input to a JWT's sign function is the following concatenation: header + "." + payload
. So if you want to verify a signature, you need to do that against that concatenation.
Once you have imported your keys as SecKey
, e.g. using SecKeyCreateWithData
, you should be able to just use iOS's Security framework to verify the signature somewhat like this:
let parts = token.components(separatedBy: ".")
let header = parts[0]
let payload = parts[1]
let signature = Data(base64URLEncoded: parts[2])!
let signingInput = (header + "." + payload).data(using: .ascii)!
SecKeyVerifySignature(publicKey, .rsaSignatureMessagePKCS1v15SHA256, signingInput as CFData, signature as! CFData, nil)
Verify JWT Token Signature
You could do this:
- fetch the public key once, store it on your server
- a request comes in, try to verify the signature using the stored public key
- if this fails, fetch the public key again, store it
- try to verify the signature a second time
This would allow you to know about a changed public key as soon as it is necessary.
Validating jwt on native platforms
You could use the Vapor package at https://github.com/vapor/jwt which does support RS256, but you'll need to fetch the JWK yourself.
Objective-C: JWT - Encode with RS256 using string data of a private key
It turned out it wasn't that hard, with a help of a workmate ;-)
Here's the solution:
NSDictionary *payload = @{@"payload" : @"hidden_information"};
id <JWTAlgorithmDataHolderProtocol> holder = [JWTAlgorithmRSFamilyDataHolder new]
.keyExtractorType([JWTCryptoKeyExtractor privateKeyWithPEMBase64].type)
.privateKeyCertificatePassphrase(nil)
.algorithmName(JWTAlgorithmNameRS256)
.secret(<string of the private key as above>);
JWTCodingResultType *result = [JWTEncodingBuilder encodePayload:payload]
.addHolder(holder)
.result;
NSString *token = result.successResult.encoded;
NSError *error = result.errorResult.error;
JWT SecurityTokenInvalidSignatureException using RS256 PII is hidden
It turns out that the KeySize for X509SecurityKey needs to be at least 1024 in length for verifying. This is not obvious from the exception, since it is hidden with the [PII is hidden] filter.
Adding the following line made the exception text a lot more useful (add to ConfigureServices
method in Startup.cs
):
IdentityModelEventSource.ShowPII = true;
The new exception text:
'System.ArgumentOutOfRangeException: IDX10631: The 'Microsoft.IdentityModel.Tokens.X509SecurityKey' for verifying cannot be smaller than '1024' bits. KeySize: '512'.
Increasing the length of the assymetric key to 1024 solved the problem.
Related Topics
Swift: Protocol VS. Struct VS. Class
Restkit, Coredata and Swift - I Can't Seem to Fetch Results Back Out
Passing Data Between View Controllers Without Segue
Use More Than One Firebase Database in Single App - Swift
How to Send Msmessage in Messages Extension
How to Get the Correct Current Time in iOS
Sectioning Tableview and Rows with Core Data Swift
Uiview Rounded Corner - Swift 2.0
iOS Pod Install Gcm and Pnchartswift
API to Capture Live Photos in iOS9
Xcode 8 Memory Graph Says "No Selection" and Not Working
Using Haneke to Cache Then Play Mp4 Files with Avplayer
iOS Swift No Such File or Directory in Debug-Iphoneos