【问题标题】:How to generate an RSA asymmetric Key Pair in Swift for IOS?如何在 Swift 中为 IOS 生成 RSA 非对称密钥对?
【发布时间】:2015-05-04 16:21:06
【问题描述】:

我需要一种在 Swift 中生成 RSA 非对称密钥对的方法。我不需要将它存储在钥匙串或任何东西中。我只需要生成一个密钥对并将两个密钥都放入字符串变量中。

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

Web 服务稍后将使用该公钥来加密一次性密码等值以及发往 IOS 应用程序的其他敏感值。我将为从 IOS 应用程序流向 Web 服务的小段数据实施类似的方案。

developer.apple.com 上显示了在 Swift 中生成密钥对的唯一记录 API 声明:

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

我试图弄清楚如何使用它,但 XCode 不喜欢下划线,我不确定我实际上应该用它做什么或如何使用它。

即使 XCode 会接受它,我也不确定如何调用该函数以及传递什么值等。我在顶部添加了“import Security”,所以这不是问题。

这太难了,这太荒谬了。我要做的就是生成一个非对称密钥对。

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

我使用 Swift 是因为我非常讨厌 Objective C。Swift 是我最终投身 IOS 开发的原因。

我不知道如何将 Objective C 类与 Swift 集成,如果有的话,我真的更希望有一个纯 Swift 解决方案。如果没有,我将不胜感激有关如何集成 Objective C 解决方案并使其工作的一些指示。

上面的sn-p是苹果提供的唯一函数调用,自然是不完整的,没有意义,也不起作用。

【问题讨论】:

  • 查看我对this question 的回答,了解从 Swift 调用 SecKeyGeneratePair() 的示例。它不是异步对,但应该可以帮助您。
  • "Async" 只是表示调用在后台运行,完成后调用回调返回密钥对,而 SecKeyGeneratePair 在运行线程中执行并返回密钥。键是一样的。
  • 我知道这是一个迟到的回复。但是还有人在找这个,请参考medium.com/@nipunr/…

标签: ios swift cryptography rsa


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 据我所知,Heimdall 使用 RSA 完成所有操作除了 生成密钥对,这就是帖子所询问的内容。
    • @OgreCodes Heimdall 确实生成密钥对。
    猜你喜欢
    • 2021-05-08
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2019-08-12
    • 2010-11-10
    • 2023-01-14
    相关资源
    最近更新 更多