14

I create the key pairs of public and private using 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) {

    }

Then I got the keys like below

Public Key

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

Private Key

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

But I don't want to generate like above.

I except the keys like below

Public Key

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

Private Key

-----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. How to convert the keys generated by SecKeyGeneratePair to -----BEGIN RSA PUBLIC KEY----- ................ -----END RSA PUBLIC KEY----- format
caldera.sac
  • 4,918
  • 7
  • 37
  • 69
Alwin
  • 1,476
  • 3
  • 19
  • 35
  • can try with this link https://github.com/trailofbits/SecureEnclaveCrypto/tree/master/SecureEnclaveSwift – BHAVIK Aug 28 '17 at 08:24

3 Answers3

13

Please try this :

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

var publicKey : SecKey?
var privateKey : SecKey?;

let 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))")
}
Mike
  • 623
  • 6
  • 26
Vini App
  • 7,339
  • 2
  • 26
  • 43
  • 1
    I generated the keys using this. Now I want to sign a piece of data using the same private key, I am getting the error `algid:encrypt:RSA:PKCS1: algorithm not supported by the key`. I want to use rsaEncryptionPKCS1 algorithm. function: `guard let signedData = SecKeyCreateSignature(myPrivateKey, SecKeyAlgorithm.rsaEncryptionPKCS1, data as CFData, &error) as Data? else { return nil } ` – Mahesh Haldar Feb 23 '20 at 07:40
  • @Vini App what are publicKey and privateKey ? how do we get them ? – Max Mar 05 '20 at 13:00
  • How I can generate new key pair on each call? since this is giving me the same keys every single time. – Chetan A May 06 '20 at 22:31
  • the bytes for the keys are null. getting errors when tring to CreateSignature. Bad Access. – Mike Jun 03 '20 at 13:39
2

You need to convert public/private key pair for external representation using SecKeyCopyExternalRepresentation method and then convert your Data into base64 encoded string which is just PEM format, using base64EncodedString(options: ) method. Refer the code here

Milad Faridnia
  • 9,113
  • 13
  • 65
  • 78
Rahul Kumar
  • 3,009
  • 2
  • 16
  • 22
-1

At first you need to obtain raw bitstreams (data) representing your key pair see how to do it here

What you need, is just base64 encoded string representing obtained data, with header and footer as is in your example which is generally known as PEM format

How? Check data.base64EncodedString()

Warning!!! Exporting private key is ... sorry for the words ... stupid idea

user3441734
  • 16,722
  • 2
  • 40
  • 59