¿Cómo generar keys públicas y privadas RSA usando Swift 3?

Creo los pares key de público y privado utilizando SecKeyGeneratePair.

ViewController

import UIKit import Security class ViewController: UIViewController { @IBOutlet weak var textFld: UITextField! @IBOutlet weak var encryptedTextFld: UITextView! @IBOutlet weak var decryptedTextFld: UITextView! var statusCode: OSStatus? var publicKey: SecKey? var privateKey: SecKey? override func viewDidLoad() { super.viewDidLoad() let publicKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"com.xeoscript.app.RsaFromScrach.public".data(using: String.Encoding.utf8)! as NSObject] let privateKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"com.xeoscript.app.RsaFromScrach.private".data(using: String.Encoding.utf8)! as NSObject] var keyPairAttr = [NSObject: NSObject]() keyPairAttr[kSecAttrKeyType] = kSecAttrKeyTypeRSA keyPairAttr[kSecAttrKeySizeInBits] = 2048 as NSObject keyPairAttr[kSecPublicKeyAttrs] = publicKeyAttr as NSObject keyPairAttr[kSecPrivateKeyAttrs] = privateKeyAttr as NSObject statusCode = SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey) if statusCode == noErr && publicKey != nil && privateKey != nil { print("Key pair generated OK") print("Public Key: \(publicKey!)") print("Private Key: \(privateKey!)") } else { print("Error generating key pair: \(String(describing: statusCode))") } } @IBAction func encryptPressed(_ sender: Any) { } @IBAction func decryptPressed(_ sender: Any) { } 

Luego obtuve las keys como a continuación.

Llave pública

 <SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 4, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: B4854E2DA6BA5EBC96C38BD44078D314E4504D130A03018ACD17D0F6679C3B6C9937B5D932A635AEAC32B9245EC400208C1F79932174EF804468D0DCE40DAF5B544CF9E4BCD7C49BA5D0BF3F8246B89B57A3A910CBB5200DCA6145E3EE216CE9C4A3283F1027AA15F7543BD3BEFF35BE24EE709CF8EB12545970AFFDA38CA11410ECA20A8F428D228ED07BF5399A2F55D93D7C143BAFA59A08E4FF932C3A689FA7F3F166B79A43837028319CB383F716B594F317ED6E20D7A8003190A13BC132D5B13708EDAEA3E2012B16CF37437BB617070D9A6DDFE55884A79BD530E4E654B823A8BBBF0AA777C8E46E94BD83E1C59EC6E1D34E69405640C309515243AA8D, addr: 0x608000420e80> 

Llave privada

 <SecKeyRef algorithm id: 1, key type: RSAPrivateKey, version: 4, block size: 2048 bits, addr: 0x60000003b960> 

Pero no quiero generar como antes.

Excepto las teclas como a continuación

Llave pública

 -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA0bipoOhkkvPxcsyOzcqsIUeVe0+iwe8W7N4EbHZMgujRERu1TPpy UcCO0uuKmm1TU09Kl40rRvDbtgB1YcGV3FPnNp3sOyFVsdyZ5bzxZtyyLrSWtj/n bLnGwaG9xJSwd2R/pTQLzOLV5KldwD2eUb3Z4Z4e9Z8II7eWgGaCLLqbrtEAa05N EqARckxrzJ1S3j+59h4AQovF72KI90/kRPryT2OGDiVlJ6CTjn2ZnTYcx65X6Rwf AeJKHZAGhw96j9tXyS+dJcXy4IBUTi3PXw0aEfhHQr/JsSHuMp/8mrhVJEokXb1C gKDZgJXujpGhCBdztHBAJxLBQMlODg7srwIDAQAB -----END RSA PUBLIC KEY----- 

Llave privada

 -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAsfxMagVKY5++61Kot0esyhEOesqyQlZNvWbqMBcOoaOAb3pk LvwaGJ2YtD12u4yDEKcY5rpX7B/2t8GBHf+74NG47zAutf4Gf6qgQRUmIx2b7i4k WBt3KIifb/Zfs9KVJLhD4007bg1OtXA4kIhhXiuvhajDjDLOEthogF45CkJe+N67 JnH5hVW5CqBxPyRCrWCFbEHcXs5H515JV/Kz1+JVrB2/M03fW751wptO2GdGwsde ofqQzY+WUzqUihXigIjAVLFRemky3HpwuhzXUJn6A0ZD4tkk1JLstpSSJdBpH+L2 b9QlOitehxFgRsYmto+idpD1XrS9UyUtmpbTuwIDAQABAoIBAQCYvrAJcJ7lnmtn Ytm96LoF89tcT+Xpfk1bFR43xSHeYAXSJdQiamIu69joHbNuwuib+vsoz5Sy5L+D 9YHMb/MZvoIaa1w6/VUwbQr4r6C6FCgEoP65ymBZnd5OZL6/ASLTj3tbb6VoDe2V UkiI6TG+cnlAmJOxFsy5aZVNTQ9gmCMS0+AdpTbDsxTPg3y0EKFXeVRyKjq0lO9m p3G5yHkFjzWWY6s5XHx27gDTt8eXg/un72Qsz1rh5iUnAoxrga0Oco3Yk9DMvMwz a1I1Lo5fpB6FbTGX3k24heSnLDFEnlBvsBBg0g/n/qgwoZJ81MgG8Q4kAfeScuCI sYVnHEBpAoGBAOpnrKEkyhk1rXG4Md+z1/odhqx89mV7mF1ttW4IhFcwpJSMohsG r27Ic87whkpRxz2Mwj3B5WPGne4UkbvniH46n3jEW7ZIUF+ASVWkjMaGJWtOqSLC I19Snie9WvpREwaCVuvT2l4IeM1WL5gKotBwa3csZgGYH6gcyW5Ipbo/AoGBAMJh /+WXbohF4+A989q0jYjRRhKwUJAYeK8/AePrx8MnAXnRd09TiqeGn0Xig/RNZ0RE 96/TC1dTIBIHk5aDMy3vQhhYF0KbwcQWmCOnGo1qNTTaWTa3UitFMWf0hO0HuZtp RyD1YwhHP0W2tiK2GVjCreqIYASCpYKLq5Qq1K+FAoGARk2h8RLfqn/27UyZaMa/ 2DxS0BkKrZVMNXlaGQ5k4uGr+wHS/NgcddWZJk/tdwzf/Q3ilDM7YZmIdIemzfy7 a2CZw9bgyuMVeA85733S2xgQ0QZepBYmFcjptnGMf9chJaqh90krDVjtImjfDXLj MjEFilC+p2vA0uMPZwxS6HECgYAc5dLUQBoHmlRRTwSEvBjagToopxujAHBYpUZT qwbMpWzbvl89ZM8VLrdY/V7en+89P/+OnRJvjgUTiRrQ4npmVs59rgLvPRamXzGJ A1u4MFTuoZNnxgMqOaQprzlfv6lBSHpxlOl/HpByfcJAENBd2LtgRZv4r6+JY9hD M8bgvQKBgCDTSCLj5c1CYyuJMdrz9L5+xLFmrmL48djhK460ZcmcZ/gP808CyXx/ sDneow+JWt7Jb3p5zyUvvq1aDGNSsn4plB2rg7AqtoHcZYyFFZGI/K/b6JZna1yu FUYOfcanunabxY1wPQxuvR+AEuufBjB0aKg+qkLCCN1HYQtLs+N8 -----END RSA PRIVATE KEY----- 
  1. Cómo convertir las keys generadas por SecKeyGeneratePair a -----BEGIN RSA PUBLIC KEY----- ................ -----END RSA PUBLIC KEY----- formatting

Intenta esto:

 let publicKeyAttr: [NSObject: NSObject] = [ kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"com.xeoscript.app.RsaFromScrach.public".data(using: String.Encoding.utf8)! as NSObject, kSecClass: kSecClassKey, // added this value kSecReturnData: kCFBooleanTrue] // added this value let privateKeyAttr: [NSObject: NSObject] = [ kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"com.xeoscript.app.RsaFromScrach.private".data(using: String.Encoding.utf8)! as NSObject, kSecClass: kSecClassKey, // added this value kSecReturnData: kCFBooleanTrue] // added this value var keyPairAttr = [NSObject: NSObject]() keyPairAttr[kSecAttrKeyType] = kSecAttrKeyTypeRSA keyPairAttr[kSecAttrKeySizeInBits] = 2048 as NSObject keyPairAttr[kSecPublicKeyAttrs] = publicKeyAttr as NSObject keyPairAttr[kSecPrivateKeyAttrs] = privateKeyAttr as NSObject statusCode = SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey) if statusCode == noErr && publicKey != nil && privateKey != nil { print("Key pair generated OK") var resultPublicKey: AnyObject? var resultPrivateKey: AnyObject? let statusPublicKey = SecItemCopyMatching(publicKeyAttr as CFDictionary, &resultPublicKey) let statusPrivateKey = SecItemCopyMatching(privateKeyAttr as CFDictionary, &resultPrivateKey) if statusPublicKey == noErr { if let publicKey = resultPublicKey as? Data { print("Public Key: \((publicKey.base64EncodedString()))") } } if statusPrivateKey == noErr { if let privateKey = resultPrivateKey as? Data { print("Private Key: \((privateKey.base64EncodedString()))") } } } else { print("Error generating key pair: \(String(describing: statusCode))") } 

Al principio, necesita get flujos de bits sin procesar (datos) que representan su par de keys. Vea cómo hacerlo aquí.

Lo que necesita es una cadena codificada en base64 que representa los datos obtenidos, con encabezado y pie de página como en su ejemplo, que generalmente se conoce como formatting PEM

¿Cómo? Comtesting data.base64EncodedString()

¡¡¡Advertencia!!! Exportar key privada es … perdón por las palabras … estúpida idea

Necesita convertir un par de keys públicas / privadas para representación externa usando el método SecKeyCopyExternalRepresentation y luego convertir sus datos en una cadena codificada en base64 que es solo un formatting PEM, usando el método base64EncodedString (opciones:) . Consulte el código aquí