yourkarma / JWT

A JSON Web Token implementation in Objective-C.
MIT License
351 stars 107 forks source link

Signature not valid according to jwt.io #192

Open drewpitchford opened 6 years ago

drewpitchford commented 6 years ago

New Issue Checklist

Issue Info

Info Value
Platform Name iOS
Platform Version 11.3
Integration Method manually
Xcode Version Xcode 9.3
Repro rate all the time (100%)

Issue Description and Steps

I am integrating JWT into an SDK I am writing. When attempting to encrypt and sign some info to send to our server, I get errors in the signature. I double checked by pasting the encrypted data into jwt.io's tool. It decrypts the headers and payload fine; the only issue is "Signature is invalid". I've basically copy/pasted the example from the docs and still see this error. Below is my code

- (nullable AuthenticationRequestParameters *)ms_getAuthenticationRequestParameters:(NSError *__autoreleasing  _Nullable *)error {

    NSString *deviceData = [ThreeDSv2Service shared].attributeString;
    NSString *alg = @"HS256";
    id<JWTAlgorithmDataHolderProtocol> signHolder = [JWTAlgorithmRSFamilyDataHolder new].algorithmName(alg).secret([[self.sdkEphemeralPrivateKeyJwk dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]);
    JWTCodingBuilder *signBuilder = [JWTEncodingBuilder encodePayload:[FormatHelper JSONObjectWithString:deviceData]].addHolder(signHolder);
    JWTCodingResultType *result = signBuilder.result;
    NSString *deviceDataEncrypted = @"";
    if(result.successResult) {

        deviceDataEncrypted = result.successResult.encoded;
        NSLog(@"Device data encrypted: %@", deviceDataEncrypted);
    }
    else {

        NSLog(@"Error signing: %@", result.errorResult.error);
    }

    if(localError) {

        *error = [NSError errorWithDomain:kErrorDomainDefault
                                     code:SDKRuntimeException
                                 userInfo:@{kSDKErrorUserInfoMessageKey: [[ErrorsHelper shared] descriptionFor:FailedToEncryptDeviceInfo], kSDKErrorUserInfoCodeKey: [[ErrorsHelper shared] codeFor:FailedToEncryptDeviceInfo]}];
        return nil;
    }

    NSString *sdkAppID = [ApplicationIDService applicationID];
    AuthenticationRequestParameters *parameters = [[AuthenticationRequestParameters alloc] initWithSDKTransactionId:self.transactionId
                                                                                                         deviceData:deviceDataEncrypted
                                                                                              sdkEphemeralPublicKey:self.sdkEphemeralPublicKeyJwk
                                                                                                           sdkAppID:sdkAppID
                                                                                                 sdkReferenceNumber:k3DSGlobalSDKReferenceNumber
                                                                                                     messageVersion:k3DSGlobalMessageVersion];
    return parameters;
}

Example encrypted output:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJEViI6IjEuMCIsIkREIjp7IkMwMDciOiI0QTU2MEQyQi1EMEQ1LTQzNzYtQjUxMC0wREY3QTlCNkRDRDIiLCJJMDA0IjoiQXJpYWwtQm9sZEl0YWxpY01ULEFyaWFsLUJvbGRNVCxBcmlhbC1JdGFsaWNNVCxBcmlhbE1UIiwiU1cwMyI6IjExMDEwMCIsIkMwMTEiOiIzNS45NDIiLCJJMDA5IjoiMTQuMDAwMDAwIiwiQzAwNSI6ImVuX1VTIiwiSTAwMiI6IjAiLCJTVzAxIjoiMTEwMTAwIiwiSTAxMyI6Ii01IiwiSTAwNyI6IjE4LjAwMDAwMCIsIkMwMDMiOiJpT1MiLCJJMDExIjoiYjM4YTNmZDdkMTdmMjA4NjYxM2IyMTUxMGNiMTk0Y2Q0ZmE1NDIxZjU0ZDRmOTE4YWJjMDE5NmQ3ZmYwYjFkOCIsIkMwMDgiOiI2Njd4Mzc1IiwiSTAwNSI6Ii5TRlVJVGV4dCIsIlNXMDQiOiIwMDEwMTAiLCJDMDEyIjoiLTg2LjgyNyIsIkMwMDEiOiJpUGhvbmU5LDEiLCJDMDA2IjoiLTUiLCJJMDAzIjoiQWNhZGVteSBFbmdyYXZlZCBMRVQsQWwgTmlsZSxBbWVyaWNhbiBUeXBld3JpdGVyLEFwcGxlIENvbG9yIEVtb2ppLEFwcGxlIFNEIEdvdGhpYyBOZW8sQXJpYWwsQXJpYWwgSGVicmV3LEFyaWFsIFJvdW5kZWQgTVQgQm9sZCxBdmVuaXIsQXZlbmlyIE5leHQsQXZlbmlyIE5leHQgQ29uZGVuc2VkLEJhbmdsYSBTYW5nYW0gTU4sQmFza2VydmlsbGUsQm9kb25pIDcyLEJvZG9uaSA3MiBPbGRzdHlsZSxCb2RvbmkgNzIgU21hbGxjYXBzLEJvZG9uaSBPcm5hbWVudHMsQnJhZGxleSBIYW5kLENoYWxrYm9hcmQgU0UsQ2hhbGtkdXN0ZXIsQ29jaGluLENvcHBlcnBsYXRlLENvdXJpZXIsQ291cmllciBOZXcsRGFtYXNjdXMsRGV2YW5hZ2FyaSBTYW5nYW0gTU4sRGlkb3QsRXVwaGVtaWEgVUNBUyxGYXJhaCxGdXR1cmEsR2VlemEgUHJvLEdlb3JnaWEsR2lsbCBTYW5zLEd1amFyYXRpIFNhbmdhbSBNTixHdXJtdWtoaSBNTixIZWl0aSBTQyxIZWl0aSBUQyxIZWx2ZXRpY2EsSGVsdmV0aWNhIE5ldWUsSGlyYWdpbm8gTWFydSBHb3RoaWMgUHJvTixIaXJhZ2lubyBNaW5jaG8gUHJvTixIaXJhZ2lubyBTYW5zLEhvZWZsZXIgVGV4dCxLYWlsYXNhLEthbm5hZGEgU2FuZ2FtIE1OLEtlZmEsS2htZXIgU2FuZ2FtIE1OLEtvaGlub29yIEJhbmdsYSxLb2hpbm9vciBEZXZhbmFnYXJpLEtvaGlub29yIFRlbHVndSxMYW8gU2FuZ2FtIE1OLE1hbGF5YWxhbSBTYW5nYW0gTU4sTWFya2VyIEZlbHQsTWVubG8sTWlzaGFmaSxNeWFubWFyIFNhbmdhbSBNTixOb3Rld29ydGh5LE5vdG8gTmFzdGFsaXEgVXJkdSxPcHRpbWEsT3JpeWEgU2FuZ2FtIE1OLFBhbGF0aW5vLFBhcHlydXMsUGFydHkgTEVULFBpbmdGYW5nIEhLLFBpbmdGYW5nIFNDLFBpbmdGYW5nIFRDLFNhdm95ZSBMRVQsU2luaGFsYSBTYW5nYW0gTU4sU25lbGwgUm91bmRoYW5kLFN5bWJvbCxUYW1pbCBTYW5nYW0gTU4sVGVsdWd1IFNhbmdhbSBNTixUaG9uYnVyaSxUaW1lcyBOZXcgUm9tYW4sVHJlYnVjaGV0IE1TLFZlcmRhbmEsWmFwZiBEaW5nYmF0cyxaYXBmaW5vIiwiU1cwMiI6IjExMDEwMCIsIkMwMTAiOiIwLjAuMC4wIiwiSTAwOCI6IjEyLjAwMDAwMCIsIkMwMDQiOiIxMS4yIiwiSTAwMSI6IjgzOTg4NDkzLUM1NUUtNEEyOC1BMjgzLUZDNzNFREVGNUI4MiIsIkkwMTIiOiJlbi1VUyIsIkMwMDkiOiI0OGY1ZGVkZjE2MGJlMzk1ZTBmZDMyNjE2NmM2NDA2OTgzNGJhNDAzYzUzMDRmNTgzMzZkYzRjYjBhNTgyNGM5IiwiSTAwNiI6IjE3LjAwMDAwMCIsIlNXMDUiOiIxMTAxMDAiLCJDMDAyIjoiaVBob25lIiwiSTAxMCI6IiJ9LCJTVyI6WyJTVzA0Il0sIkRQTkEiOnt9fQ==.R2eHc8xSQqj0Ou659tsCHIrM847IR/J6nENgtwnmhOY=

Is there something I'm missing here? I'd appreciate any help! Thanks!

lolgear commented 6 years ago

@drewpitchford Complicated example. However, check parameters:

    NSString *alg = @"HS256";
    [JWTAlgorithmRSFamilyDataHolder new].algorithmName(alg);

Something wrong here. Algorithm should be "RS256".

Besides, try to separate code in pieces.

    NSString *alg = @"HS256";
    id<JWTAlgorithmDataHolderProtocol> signHolder = [JWTAlgorithmRSFamilyDataHolder new].algorithmName(alg).secret([[self.sdkEphemeralPrivateKeyJwk dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]);

You can't check here secret that you pass to holder. Also you can't check data from which you create base64 string.

    NSString *alg = @"HS256";
    NSData *secretData = [self.sdkEphemeralPrivateKeyJwk dataUsingEncoding:NSUTF8StringEncoding];
    NSString *secretString = [secretData base64EncodedStringWithOptions:0];
    id<JWTAlgorithmDataHolderProtocol> signHolder = [JWTAlgorithmRSFamilyDataHolder new]
    .algorithmName(alg)
    .secret(secretString);

It becomes a bit readable.

drewpitchford commented 6 years ago

Yes, I agree it's not clean code. It's a proof of concept for now. I'll try RS256.

drewpitchford commented 6 years ago

@lolgear Does this lib support JWE? I don't see any specific mention of it anywhere.

To be clear, JWE format such as x.x.x.x.x rather than JWS 'x.x.x'

lolgear commented 6 years ago

@drewpitchford No, it doesn't support it yet.