Получить пару ключей RSA в виде строки после генерации в iOS (Swift)?

Какой лучший способ сгенерировать пару ключей RSA в iOS и получить их как String. Я видел пару библиотек, которые могут генерировать, но я не могу получить закрытый ключ в виде строки. Кто-нибудь знает lib или способ получить закрытый ключ в String?

В настоящее время я генерирую пару ключей таким образом

var statusCode: OSStatus
var publicKey: SecKey?
var privateKey: SecKey?

let publicKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"publicTag" as NSObject]
let privateKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"privateTag" 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(publicKey!)
    print(privateKey!)

} else {
  print("Error generating key pair: \(statusCode)")
}

Это в SecKey. Как конвертировать их в строку? или есть другой способ сделать это?

1 ответ

Вот код, использующий SecItemCopyMatching:

let PublicKeyTag = "publicTag"
let PrivateKeyTag = "privateTag"

let publicKeyAttr: [NSString: Any] = [
    kSecAttrIsPermanent: NSNumber(value: true),
    kSecAttrApplicationTag: PublicKeyTag
]
let privateKeyAttr: [NSString: Any] = [
    kSecAttrIsPermanent: NSNumber(value: true),
    kSecAttrApplicationTag: PrivateKeyTag
]

let keyPairAttr: [NSString: Any] = [
    kSecAttrKeyType: kSecAttrKeyTypeRSA,
    kSecAttrKeySizeInBits: 2048 as NSObject,
    kSecPublicKeyAttrs: publicKeyAttr,
    kSecPrivateKeyAttrs: privateKeyAttr
]

var publicKey: SecKey?
var privateKey: SecKey?
var statusCode: OSStatus
statusCode = SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey)

if statusCode == noErr && publicKey != nil && privateKey != nil {
    print(publicKey!)
    print(privateKey!)
} else {
    print("Error generating key pair: \(statusCode)")
}

var dataPtr: AnyObject?
let query: [NSString: Any] = [
    kSecClass: kSecClassKey,
    kSecAttrApplicationTag: PrivateKeyTag,
    kSecReturnData: NSNumber(value: true)
]
statusCode = SecItemCopyMatching(query as CFDictionary, &dataPtr)

let privateKeyData = dataPtr as! Data
let privateKeyString = privateKeyData.base64EncodedString(options: [])
print(privateKeyString)

privateKeyData кажется, содержит закодированную информацию ASN.1. Конечный результат кодируется в Base64.

Попробуйте метод ниже, если он кому-то поможет. Добавьте приведенный ниже метод в свой код с входным параметром типа SecKey.

 func secKeyToString(key:SecKey) {
        var error:Unmanaged<CFError>?
        if let cfData = SecKeyCopyExternalRepresentation(key, &error) {
            let base64KeyString = (cfData as Data).base64EncodedString()
            print("Sec key in string:\(base64KeyString)")
        }
    }

Вы также можете создать расширение для класса SecKey с той же кодовой базой и вернуть строку в кодировке base 64, как показано ниже: extension SecKey {

    func toString()-> String{
        var error:Unmanaged<CFError>?
        let cfData = SecKeyCopyExternalRepresentation(self, &error)
        let base64KeyString = (cfData as! Data).base64EncodedString()
        return base64KeyString
    }
}

Используйте следующий метод:

//publicSecKey is your public key in SecKey format
let keyInStringFormat = publicSecKey.toString()
print("public key in string:\(keyInStringFormat)")
Другие вопросы по тегам