yourkarma / JWT

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

ES256 error :Unable to decode the provided data. #226

Open sshallow opened 3 years ago

sshallow commented 3 years ago

New Issue Checklist

Issue Info

Info Value
Platform Name ios
Platform Version 14.1
CocoaLumberjack Version 3.0.0-beta.12
Integration Method cocoapods
Xcode Version Xcode 12
Repro rate all the time (100%)

Issue Description and Steps

I want to create a jwt token via oc in order to use App Store Connect API.

Error

encode failed, error: Error Domain=NSOSStatusErrorDomain Code=-26275 "Unable to decode the provided data." UserInfo={NSLocalizedDescription=Unable to decode the provided data.}

Code

// fill it
claimsSet.issuer = @"f2a3d6c9-2d1b-488a-afe0-2xxxxxx";
claimsSet.expirationDate = [[NSDate date] initWithTimeIntervalSinceNow: 20 * 60];
claimsSet.audience = @"appstoreconnect-v1";

// encode it
NSString *privateKey = [self pemKeyStringFromFileWithName];
NSString *algorithmName = JWTAlgorithmNameES256;
NSDictionary *headers = @{@"kid":@"C999Sxxxxxx"};

id<JWTAlgorithmDataHolderProtocol>holder = [JWTAlgorithmHSFamilyDataHolder new].algorithmName(algorithmName).secret(privateKey);

JWTCodingResultType *result = [JWTEncodingBuilder encodeClaimsSet:claimsSet].headers(headers).addHolder(holder).result;

NSString *encodedToken = result.successResult.encoded;
if (result.successResult) {
    // handle encoded result
    NSLog(@"encoded result: %@", result.successResult.encoded);
}
else {
    // handle error
    NSLog(@"encode failed, error: %@", result.errorResult.error);
}

ps

This is the corresponding ruby script, it works

require "base64"
require "jwt"
ISSUER_ID = "f2a3d6c9-2d1b-488a-afe0-296xxxxx"
KEY_ID = "C999S5xxx"
private_key = OpenSSL::PKey.read(File.read("/Users/smart/AuthKey_C999xxxxx.p8"))
token = JWT.encode(
   {
    iss: ISSUER_ID,
    exp: Time.now.to_i + 20 * 60 ,
    aud: "appstoreconnect-v1"
   },
   private_key,
   "ES256",
   header_fields={
     kid: KEY_ID }
 )
puts token
sshallow commented 3 years ago

I seem to find the source of the problem: The privateKey is always empty. By tracking the source code, I found that there was a problem in the process of converting data to key.

JWTCryptoSecurity.h

QQ20201111-151646@2x

SecItem.h (framework )

es256

But 'kSecAttrKeyTypeECDSA' is unavailable: not available on iOS

lolgear commented 3 years ago

@sshallow thanks for information! Have you tried to change key to TypeEC and create private key from your data?

sshallow commented 3 years ago

@lolgear I tried to use kSecAttrKeyTypeEC to create, the result of SecKeyCreateWithData was empty. (Picture 1 is the process of kSecAttrKeyTypeEC)

lolgear commented 3 years ago

@sshallow Could you share an example project? I would like to close many bugs before pre-release API V3