YouSS
YouSS

Reputation: 570

JWT 'RS256' Algorithm issue

I used this library for generating JWT token here is my code :

func generateJWT() -> String{
    let claim = JWTClaimsSet()
    claim.issuer = "xxxxxx"
    claim.audience = "https://www.googleapis.com/oauth2/v4/token"
    claim.issuedAt = NSDate()
    claim.expirationDate = NSDate()

    let header = ["alg":"RS256","typ":"JWT"]
    let algorithm = JWTAlgorithmFactory.algorithmByName("RS256")

    let encodeBuilder = JWT.encodeClaimsSet(claim)
    let jwt = encodeBuilder.secret("secret").algorithm(algorithm).headers(header).encode

    return jwt
}

But i'm getting this error :

2016-03-30 16:51:23.274 JWTObjc[3217:74974] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[2]'

I did anything wrong ?

Thank's in advance

Upvotes: 0

Views: 1120

Answers (2)

Dodi
Dodi

Reputation: 141

i use PKCS1 with RS256

 func encryptPayload(payload:[AnyHashable:Any])->String?
{
    var resultStr: String?

    var publicKeyCrypto: JWTCryptoKeyProtocol? = nil
    do {
        publicKeyCrypto = try JWTCryptoKeyPublic(pemEncoded: AppConstant.Scurity.publicKey, parameters: nil)
    }
    catch {
        NSLog("error: \(error)")
    }

    guard let theCrypto = publicKeyCrypto else {
        return nil
    }

    do {

        let privateKeyCrypto = try JWTCryptoKeyPrivate(pemEncoded: AppConstant.Scurity.privateKey, parameters: nil)

        guard let holder = JWTAlgorithmRSFamilyDataHolder().signKey(privateKeyCrypto)?.secretData(AppConstant.Scurity.privateKey.data(using: .utf8))?.algorithmName(JWTAlgorithmNameRS256) else {return nil}

        let headers : [AnyHashable:Any] = ["alg": "RS256","typ": "JWT"]

        guard let encoding = JWTEncodingBuilder.encodePayload(payload).headers(headers)?.addHolder(holder) else {return nil}

        let result = encoding.result

        print(result?.successResult?.encoded ?? "Encoding failed")
        print(result?.errorResult?.error ?? "No encoding error")

        let verifyDataHolder = JWTAlgorithmRSFamilyDataHolder().signKey(theCrypto)?.secretData(AppConstant.Scurity.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)")
        }
        resultStr = result?.successResult.encoded
    } catch {
        print(error)
    }
    return resultStr
}

Upvotes: 0

Carl Lindberg
Carl Lindberg

Reputation: 2947

HMAC signature signing/verification involves a shared secret known by both sides, thus the use of the .secret("secret") method there.

RSA is a public/private key system, where the signer has the private key, and the verifier has only the public key. So, to create the signed JWT, you need the private key instead. These are most often used in PKCS12 format, protected by a passphrase. It looks like that is how the JWTAlgorithmRS256 class is expecting it, so the API there looks more like .secretData(p12FileData).privateKeyCertificatePassphrase("password") instead of .secret("secret").

For verification, you probably want .secretData(certFileData) (the cert would contain the public key).

Upvotes: 1

Related Questions