如何使用Swift 3生成RSA公钥和私钥?

15

我使用SecKeyGeneratePair创建公私钥对。

视图控制器

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) {

    }

然后我得到了以下这些密钥

公钥

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

私钥

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

但我不想像上面那样生成。

我期望的密钥如下所示

公钥

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA0bipoOhkkvPxcsyOzcqsIUeVe0+iwe8W7N4EbHZMgujRERu1TPpy
UcCO0uuKmm1TU09Kl40rRvDbtgB1YcGV3FPnNp3sOyFVsdyZ5bzxZtyyLrSWtj/n
bLnGwaG9xJSwd2R/pTQLzOLV5KldwD2eUb3Z4Z4e9Z8II7eWgGaCLLqbrtEAa05N
EqARckxrzJ1S3j+59h4AQovF72KI90/kRPryT2OGDiVlJ6CTjn2ZnTYcx65X6Rwf
AeJKHZAGhw96j9tXyS+dJcXy4IBUTi3PXw0aEfhHQr/JsSHuMp/8mrhVJEokXb1C
gKDZgJXujpGhCBdztHBAJxLBQMlODg7srwIDAQAB
-----END RSA PUBLIC 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. 如何将SecKeyGeneratePair生成的密钥转换为-----BEGIN RSA PUBLIC KEY----- ................ -----END RSA PUBLIC KEY-----格式

您可以尝试使用此链接https://github.com/trailofbits/SecureEnclaveCrypto/tree/master/SecureEnclaveSwift。 - BHAVIK
3个回答

13
请试一下这个:
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))")
}

1
我使用这个生成了密钥。 现在我想使用相同的私钥对一段数据进行签名,但是我遇到了错误algid:encrypt:RSA:PKCS1: algorithm not supported by the key.我想使用rsaEncryptionPKCS1算法。函数: guard let signedData = SecKeyCreateSignature(myPrivateKey, SecKeyAlgorithm.rsaEncryptionPKCS1, data as CFData, &error) as Data? else { return nil } - Mahesh Haldar
@Vini App,公钥和私钥是什么?我们如何获取它们? - Max
我该如何在每次调用时生成新的密钥对?因为现在每次都会给我相同的密钥。 - Chetan A
密钥的字节为空。在尝试创建签名时出现错误。访问无效。 - Mike

3
你需要使用SecKeyCopyExternalRepresentation方法将公钥/私钥对转换为外部表示形式,然后使用base64EncodedString(options: )方法将你的数据转换为Base64编码字符串,这只是PEM格式。请参考此处的代码

-1

首先,您需要获取表示密钥对的原始比特流(数据)在此处查看如何执行此操作

您所需的只是代表获得的数据的Base64编码字符串,带有标题和页脚,就像您的示例中一样,通常被称为PEM格式

如何实现?请检查data.base64EncodedString()

警告!导出私钥是一个...抱歉用这个词...愚蠢的想法。


仅用于测试目的... :) - Medhi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接