如何在Swift for IOS中生成RSA非对称密钥对



我需要一种在Swift中生成RSA非对称密钥对的方法。我不需要把它存放在钥匙扣或其他东西里。我只需要生成一个密钥对,并将两个密钥插入String变量中。

密钥确实需要与另一端的PHP兼容。我将使用对称加密来保护私钥并将其存储在手机上。我将把公钥发送到用PHP实现的web服务,web服务将把公钥存储在数据库中。

该公钥稍后将被web服务用于加密值,如一次性密码和其他指定给IOS应用程序的敏感值。我将为从IOS应用程序流到web服务的小块数据实现类似的方案。

我能找到的唯一一个在Swift中生成密钥对的API声明文档显示在developer.apple.com:上

func SecKeyGeneratePairAsync(_ parameters: CFDictionary!,
                           _ deliveryQueue: dispatch_queue_t!,
                           _ result: SecKeyGeneratePairBlock!)

我试图弄清楚如何使用它,但XCode不喜欢下划线,我不确定我应该如何使用它。

即使XCode接受它,我也不确定我将如何调用该函数以及传递它的值,等等。我在顶部包含了"导入安全性",所以这不是问题所在。

这太荒谬了,这么难。我只想生成一个非对称密钥对。

用PHP、.NET、Java或任何其他语言做这件事都是小菜一碟,但我找不到任何关于Swift的清晰文档。我必须为这个应用程序使用Swift。我不想使用OpenSSL,因为它已被弃用。

我之所以使用Swift,是因为我非常讨厌目标C。Swift是我最终投入IOS开发的原因。

我不知道如何将Objective C类与Swift集成,如果有纯Swift解决方案的话,我真的宁愿有一个。如果没有,我会很感激一些关于如何集成Objective C解决方案并使其发挥作用的建议。

上面的代码片段是苹果提供的唯一函数调用,当然它是不完整的,没有意义,也不起作用。

GitHub的CertificateSigningRequestSwift_Test项目中有一个很好的例子说明了如何在Swift中实现这一点。使用对SecKeyCreateRandomKey()的单个调用,可以同时生成公钥/私钥对,并且它们将保存在密钥链中。

        let tagPublic = "com.example.public"
        let tagPrivate = "com.example.private"
        let publicKeyParameters: [String: AnyObject] = [
            String(kSecAttrIsPermanent): kCFBooleanTrue,
            String(kSecAttrApplicationTag): tagPublic as AnyObject,
            String(kSecAttrAccessible): kSecAttrAccessibleAlways
        ]
        var privateKeyParameters: [String: AnyObject] = [
            String(kSecAttrIsPermanent): kCFBooleanTrue,
            String(kSecAttrApplicationTag): tagPrivate as AnyObject,
            String(kSecAttrAccessible): kSecAttrAccessibleAlways
        ]
        //Define what type of keys to be generated here
        var parameters: [String: AnyObject] = [
            String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
            String(kSecAttrKeySizeInBits): 2048,
            String(kSecReturnRef): kCFBooleanTrue,
            kSecPublicKeyAttrs as String: publicKeyParameters as AnyObject,
            kSecPrivateKeyAttrs as String: privateKeyParameters as AnyObject,
        ]
        //Use Apple Security Framework to generate keys, save them to application keychain
        var error: Unmanaged<CFError>?
        let privateKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error)
        if privateKey == nil{
            print("Error creating keys occurred: (error!.takeRetainedValue() as Error), keys weren't created")
            return
        }
        //Get generated public key
        let query: [String: AnyObject] = [
            String(kSecClass): kSecClassKey,
            String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
            String(kSecAttrApplicationTag): tagPublic as AnyObject,
            String(kSecReturnRef): kCFBooleanTrue
        ]
        var publicKeyReturn:AnyObject?
        let result = SecItemCopyMatching(query as CFDictionary, &publicKeyReturn)
        if result != errSecSuccess{
            print("Error getting publicKey from keychain occurred: (result)")
            return
        }
        let publicKey = publicKeyReturn as! SecKey?
        //Set block size
        let keyBlockSize = SecKeyGetBlockSize(self.publicKey!)
        //Ask keychain to provide the publicKey in bits
        let query: [String: AnyObject] = [
            String(kSecClass): kSecClassKey,
            String(kSecAttrKeyType): keyAlgorithm.secKeyAttrType,
            String(kSecAttrApplicationTag): tagPublic as AnyObject,
            String(kSecReturnData): kCFBooleanTrue
        ]
        var tempPublicKeyBits:AnyObject?
        _ = SecItemCopyMatching(query as CFDictionary, &tempPublicKeyBits)
        guard let publicKeyBits = tempPublicKeyBits as? Data else {
            return
        }

Heimdall似乎就是您想要的。它易于使用,可以创建RSA密钥对、加密、解密、签名和验证。

它使用iOS/OS X密钥链来存储密钥,因此密钥以安全的方式存储。

来自GitHub Readme:

if let heimdall = Heimdall(tagPrefix: "com.example") {
    let testString = "This is a test string"
    // Encryption/Decryption
    if let encryptedString = heimdall.encrypt(testString) {
        println(encryptedString) // "cQzaQCQLhAWqkDyPoHnPrpsVh..."
        if let decryptedString = heimdall.decrypt(encryptedString) {
            println(decryptedString) // "This is a test string"
        }
    }
    // Signatures/Verification
    if let signature = heimdall.sign(testString) {
        println(signature) // "fMVOFj6SQ7h+cZTEXZxkpgaDsMrki..."
        var verified = heimdall.verify(testString, signatureBase64: signature)
        println(verified) // True
        // If someone meddles with the message and the signature becomes invalid
        verified = heimdall.verify(testString + "injected false message",
                                    signatureBase64: signature)
        println(verified) // False
    }
}

最新更新