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

问题描述 投票:0回答:4

我使用 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-----
    格式
ios swift swift3 rsa public-key
4个回答
14
投票

请尝试这个:

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))")
}

3
投票

您需要使用

SecKeyCopyExternalRepresentation
方法转换用于外部表示的公钥/私钥对,然后使用
base64EncodedString(options: )
方法将您的数据转换为 Base64 编码的字符串(即 PEM 格式)。 请参考这里的代码


0
投票

SecKeyGeneratePair
在 iOS 15 中已被弃用。从 iOS 10 开始,我们应该使用
SecKeyCreateRandomKey
。查看我的实现,用于生成 RSA 加密和解密的公钥和私钥。

我通过加密和解密字符串来测试代码。

import Security

public enum EncryptionError: Error {
    case keyGenerationFailed(line: Int)
}

public struct CypherKeyModel {
    var publicKey: SecKey
    var privateKey: SecKey

    init(publicKey: SecKey, privateKey: SecKey) {
        self.publicKey = publicKey
        self.privateKey = privateKey
    }
}


public struct CypherKeyGenerator {
    
    private var publicKey: Data
    private var privateKey: Data

    init(identifier: String) throws {
        let publicKeyId = identifier + ".public"
        let privateKeyId = identifier + ".private"
        guard let publicKeyIndentifierData = publicKeyId.data(using: String.Encoding.utf8),
              let privateKeyIndentifierData = privateKeyId.data(using: String.Encoding.utf8) else {
            throw EncryptionError.keyEncodingError(line: #line)
        }
        self.publicKey = publicKeyIndentifierData
        self.privateKey = privateKeyIndentifierData
    }

    func generateKey() throws -> CypherKeyModel {

        var error: UnsafeMutablePointer<Unmanaged<CFError>?>?

        /// Creating the public key attributes.
        let publicKeyAttr: CFDictionary = [
                     kSecAttrIsPermanent:true,
                     kSecAttrApplicationTag: publicKey,
                     kSecClass: kSecClassKey,
                     kSecReturnData: kCFBooleanTrue ?? true
        ] as CFDictionary // added this value

        /// Creating the private key attributes.
        let privateKeyAttr: CFDictionary = [
                     kSecAttrIsPermanent:true,
                     kSecAttrApplicationTag: privateKey,
                     kSecClass: kSecClassKey, // added this value
                     kSecReturnData: kCFBooleanTrue ?? true
        ] as CFDictionary // added this value

        /// Creating the parameters
        let parameters: CFDictionary = [
            kSecAttrKeyType: kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits: 1024,
            kSecPublicKeyAttrs: publicKeyAttr,
            kSecPrivateKeyAttrs: privateKeyAttr
        ] as CFDictionary

        guard let privateKey = SecKeyCreateRandomKey(parameters, error) else {
            throw EncryptionError.keyGenerationFailed(line: #line)
        }
        guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
            throw EncryptionError.keyGenerationFailed(line: #line)
        }
        return CypherKeyModel.init(publicKey: publicKey, privateKey: privateKey)
    }
}


-1
投票

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

您需要的只是代表获得的数据的base64编码字符串,其页眉和页脚如您的示例中所示,通常称为PEM格式

如何?检查

data.base64EncodedString()

警告!!!导出私钥是......抱歉的话......愚蠢的想法

© www.soinside.com 2019 - 2024. All rights reserved.