stephen
stephen

Reputation: 597

Throw ‘incorrectKeySize' error when create private key using CryptoKit EdDSA

I'm trying to Signature the privateKey according to this stackoverflow answer How do I generate a JWT to use in API authentication for Swift app, but with EdDSA algorithm.

The problem is, it always throw a incorrectKeySize error when create the privateKey. Keys are generated by openssl genpkey, do I need to do something else to encode that private key?

Below is the code:

  1. Public/Private keys are generated in console through openssl genpkey:
    openssl genpkey -algorithm ED25519 -out ed25519-private.pem \
    && openssl pkey -pubout -in ed25519-private.pem > ed25519-public.pem
  1. JWT code:
    struct Header: Encodable {
        let alg = "EdDSA"
        let typ = "ABCDEFGHIJ"
    }

    struct Payload: Encodable {
        let sub = "ABCDEFGHIJ"
        let iat = 1516239022
        let exp = 1516249022
    }
    
    private func createJWT_apple() async -> String? {
        do {
            let secret = "MC4CAQAwBQYDK2VwBCIEIE9dWdfSb3YjvA9gASX8ZY7BiQubC4jQLiwQZtUmHXrD" // This is a real key generated using openssl genpkey, but has been revoked.
            let data = Data(base64Encoded: secret)!
            let privateKey = try Curve25519.Signing.PrivateKey(rawRepresentation: data) //"incorrectKeySize" error throws here!
            
            let headerJSONData = try JSONEncoder().encode(Header())
            let headerBase64String = headerJSONData.urlSafeBase64EncodedString()
            
            let payloadJSONData = try JSONEncoder().encode(Payload())
            let payloadBase64String = payloadJSONData.urlSafeBase64EncodedString()
            
            let toSign = Data((headerBase64String + "." + payloadBase64String).utf8)
            
            let signature = try privateKey.signature(for: toSign)
            let signatureBase64String = Data(signature).urlSafeBase64EncodedString()
            
            let token = [headerBase64String, payloadBase64String, signatureBase64String].joined(separator: ".")
            return token
        } catch {
            printLog(error)
        }
        
        return nil
    }

Upvotes: 0

Views: 25

Answers (1)

stephen
stephen

Reputation: 597

I found a post on Apple Developer CryptoKit to create JWT, which explains clearly how to decode the private key produced by openssl. Just as @dave_thompson_085's comments:

PKCS8 format for private keys, which contains both an algorithm identifier with optional parameters (here ed25519) PLUS the algoirthm-dependent key data

The point is we need to extract only the private key bytes after dumpasn1 the data!

Upvotes: 0

Related Questions