Generate JWT token using RS256 algorithm

I want to generate a JWT token using RS256 algo in Swift. I do not see any support for this in the native libraries, but I am very new to this topic. Is this possible ?

@eskimo Is it possible to create a JWT using RS256 on iOS?

See here IBM codebase: https://github.com/Kitura/Swift-JWT JWT.io: https://jwt.io/libraries?language=Swift

iOS has no high-level APIs for generating JWT tokens, so you’ll have to either write or acquire a library to do this based on lower-level security primitives. I don’t have a specific recommendation for you; my job means that I’m not allowed to use third-party code so I’ve never sat down to evaluate the various JWT libraries out there.

Also, in a lot of cases my JWT requirements are sufficiently simple that I just cons up the specific code I need. For example, I wrote the code pasted in below to generate tokens per the spec in Generating Tokens for API Requests.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

// The following is modelled on the C# code in Appendix C of [RFC
// 7515][rfc7515].
//
// [rfc7515]: <https://tools.ietf.org/html/rfc7515>

extension Data {

    init?(base64URLEncodedString: String) {
        let unpadded = base64URLEncodedString
            .replacingOccurrences(of: "-", with: "+")
            .replacingOccurrences(of: "_", with: "/")
        let padCount: Int
        switch unpadded.count % 4 {
        case 0: padCount = 0
        case 1: return nil
        case 2: padCount = 2
        case 3: padCount = 1
        default: fatalError()
        }
        self.init(base64Encoded: String(unpadded + String(repeating: "=", count: padCount)))
    }

    var base64URLEncodedString: String {
        let base64 = self.base64EncodedString()
        return String(base64.split(separator: "=").first!)
            .replacingOccurrences(of: "+", with: "-")
            .replacingOccurrences(of: "/", with: "_")
    }
}

func jwtHeader(kid: String) -> String {
    struct Header: Codable {
        var alg: String
        var kid: String
        var typ: String
    }
    let header = Header(alg: "ES256", kid: kid, typ: "JWT")
    return try! JSONEncoder().encode(header).base64URLEncodedString
}

func jwtPayload(iss: String, exp: Date) -> String {
    // We round the expiry date up because it’s not clear how servers are going
    // to cope with fractional values.
    let exp = Date(timeIntervalSinceReferenceDate: exp.timeIntervalSinceReferenceDate.rounded(.up))
    struct Payload: Codable {
        var iss: String
        var exp: Date
        var aud: String
    }
    let payload = Payload(iss: iss, exp: exp, aud: "appstoreconnect-v1")
    let encoder = JSONEncoder()
    encoder.dateEncodingStrategy = .secondsSince1970
    return try! encoder.encode(payload).base64URLEncodedString
}

func jwtSignedToken(kid: String, iss: String, exp: Date, ecSECp256rKeyK keyK: Data) throws -> String {
    let header = jwtHeader(kid: kid)
    let payload = jwtPayload(iss: iss, exp: exp)
    let signingInput = "\(header).\(payload)"
    let privateKey = try P256.Signing.PrivateKey(rawRepresentation: keyK)
    let sig = try privateKey.signature(for: Data(signingInput.utf8)).rawRepresentation
    return "\(signingInput).\(sig.base64URLEncodedString)"
}

func jwtSignedToken(kid: String, iss: String, exp: Date, ecSECp256rPrivateKey privateKey: SecKey) throws -> String {
    var errorCF: Unmanaged<CFError>? = nil
    guard let keyData = SecKeyCopyExternalRepresentation(privateKey, &errorCF) as Data? else {
        throw errorCF!.takeRetainedValue()
    }
    let keyK = keyData.suffix(0x20)
    return try jwtSignedToken(kid: kid, iss: iss, exp: exp, ecSECp256rKeyK: keyK)
}

@eskimo this chunk for me has been very good reference for generating JWT. But could you pls elaborate or put up code to generating SecKey parameter for jwtSignedToken( method. from a .p8 file downloaded with apple sign in enabled ? I am trying to use it for generating JWT for POST https://appleid.apple.com/auth/token API call. I am new to this aspect of coding so finding it very difficult to any proper ref on the same.

code to generating SecKey parameter for jwtSignedToken

Check out Importing Cryptographic Keys.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Generate JWT token using RS256 algorithm
 
 
Q