I tried to generate the keys with different approaches, get the raw data but I can't find any library that transform these bytes into OpenSSH compatible public and private keys.
Approach 1:
let privateKeyParams: [String: Any] = [
kSecAttrIsPermanent as String: false,
]
let parameters: [String: Any] = [
String(kSecClass): kSecClassKey,
String(kSecAttrKeyType): kSecAttrKeyTypeECSECPrimeRandom,
String(kSecAttrKeySizeInBits): 256,
kSecPrivateKeyAttrs as String: privateKeyParams
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
throw error!.takeRetainedValue() as Error
}
guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
throw KeyGeneratorError(description: "Failed to generate the public key")
}
guard let privateKeyData = SecKeyCopyExternalRepresentation(privateKey, nil) as? Data else {
throw KeyGeneratorError(description: "Failed to extract data from key")
}
guard let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil) as? Data else {
throw KeyGeneratorError(description: "Failed to extract data from key")
}
Approach 2 (using CryptoKit):
let privateKey = Curve25519.KeyAgreement.PrivateKey()
let publicKey = privateKey.publicKey
let privateKeyData = privateKey.rawRepresentation
let publicKeyData = publicKey.rawRepresentation
Approach 3 (using SwCrypt library):
let (privateKey, publicKey) = try SwCrypt.CC.EC.generateKeyPair(256)
I always get an object of type "Data" but I cannot transform this data into an OpenSSH string of this type:
Private Key:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAZ9c1i+q
9gMY51eotxWjeRAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIPAWeGw39CgOruIW
i0N/yji4+K/r/VPdwgg6BQD3e1Y5AAAAoJ9WV+HMYQx4bPyjTprzDQfLmcl3BiCC6hSe93
c29g2jd8zMSr4fVH0ECby6iaLxlwYbvRz+gdIqpI8MpxEJ+XBzWYNWM8r9tD7wS4rHICXg
rjXnXfq6OUfiq+RzYFrn6mLYE3PwA//IsNyrnk9tHk9y4E0dj1JlYHQ4Y5LBOg3DsosTNo
qTVa9+7XrCuSxDMaXqVMgSMbBo0H8bolX/4uM=
-----END OPENSSH PRIVATE KEY-----
Public Key:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAWeGw39CgOruIWi0N/yji4+K/r/VPdwgg6BQD3e1Y5