yourkarma / JWT

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

Encoding in 3.0.0-beta.2 does not allow for using a secret that is not base64 encoded #132

Closed andriajensen closed 7 years ago

andriajensen commented 7 years ago

New Issue Checklist

Issue Info

Info Value
Platform Name iOS
Platform Version 10.3
Integration Method Cocoapods
Xcode Version Xcode
Repro rate all the time (100%)

Issue Description and Steps

I have been migrating from version 2.2.0 to 3.0.0-beta.2. In doing so, it appears the encoding no longer behaves the same. We were previously using a secret without base64 encoding. However, when sending that same secret to the encoder in 3.0.0-beta.2, a different signature is produced. In digging further, it seems that in 3.x, the secret and secretData properties both store a base64 encoded version of the secret. So, the signature is always produced with a base64 encoded version of the given secret. The server I'm communicating with is not expecting the secret to be base64 encoded, and therefore it cannot validate the signature.

The relevant code is highlighted below. Note that secret is presumably the non-base64 encoded string. However, it is calling to dataFromString which is then base64 encoding it. So, presumably, there is no way to create a JWT encoding that does not use a base64 encoded secret.

- (instancetype)secretData:(NSData *)secretData {
    self.internalSecretData = secretData;
    return self;
}

- (instancetype)secret:(NSString *)secret {
    self.internalSecretData = [self dataFromString:secret];
    return self;
}
- (NSData *)dataFromString:(NSString *)string {
    NSData *result = [JWTBase64Coder dataWithBase64UrlEncodedString:string];

    if (result == nil) {
        // tell about it?!
        NSLog(@"%@ %@ something went wrong. Data is not base64encoded", self.debugDescription, NSStringFromSelector(_cmd));
    }

    return result ?: [string dataUsingEncoding:NSUTF8StringEncoding];
}
lolgear commented 7 years ago

@andriajensen Hi! Am I right that this could be solved by adding string streamers/coders in dataHolders?

In perspective:

- (id<JWTStringCoder>)coder {
   return _coder;
}

- (NSData *)dataFromString:(NSString *)string {
   NSData *result = [self.coder dataWithString:string];   
   return result ?: [JWTDefaultStringCoder dateWithString:string]
}
lolgear commented 7 years ago

@andriajensen

Could you check latest master?

134

andriajensen commented 7 years ago

This seems like a sane approach.

andriajensen commented 7 years ago

Looks like it works with latest master. However, I'm seeing a new issue that I'll open another for.