繁体   English   中英

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

[英]How to generate an RSA asymmetric Key Pair in Swift for IOS?

我需要一种在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会接受它,我也不确定如何调用该函数以及传递它的值等等。我在顶部包含“import Security”,所以这不是问题。

这应该是如此艰难,这太荒谬了。 我想做的就是生成一个非对称密钥对。

用PHP或.NET或Java或任何其他语言执行此操作是件小事,但我找不到有关Swift的任何明确文档。 我必须使用Swift这个应用程序。 我不想使用OpenSSL,因为它已被弃用。

我正在使用Swift,因为我讨厌仇恨目标C. Swift是我最终进入IOS开发的原因。

我不知道如何将Objective C类与Swift集成,如果有的话,我真的宁愿拥有纯粹的Swift解决方案。 如果没有,我会理解如何集成Objective C解决方案并使其工作的一些指示。

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

在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自述文件:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM