我使用 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-----
-----BEGIN RSA PUBLIC KEY----- ................ -----END RSA PUBLIC KEY-----
格式请尝试这个:
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))")
}
您需要使用
SecKeyCopyExternalRepresentation
方法转换用于外部表示的公钥/私钥对,然后使用 base64EncodedString(options: )
方法将您的数据转换为 Base64 编码的字符串(即 PEM 格式)。 请参考这里的代码
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)
}
}
首先,您需要获取代表您的密钥对的原始比特流(数据)在此处查看如何操作
您需要的只是代表获得的数据的base64编码字符串,其页眉和页脚如您的示例中所示,通常称为PEM格式
如何?检查
data.base64EncodedString()
警告!!!导出私钥是......抱歉的话......愚蠢的想法