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

如何在Swift for IOS中生成RSA非对称密钥对?,ios,swift,cryptography,rsa,Ios,Swift,Cryptography,Rsa,我需要一种在Swift中生成RSA非对称密钥对的方法。我不需要把它储存在钥匙链或其他东西里。我只需要生成一个密钥对,并将两个密钥放入字符串变量中 在另一端,这些键确实需要与PHP兼容。我将使用对称加密来保护私钥并将其存储在手机上。我将把公钥发送到用PHP实现的web服务,web服务将把公钥存储在数据库中 该公钥稍后将被web服务用于加密值,如一次性密码和其他指定给IOS应用程序的敏感值。我将为从IOS应用程序流向web服务的小块数据实现类似的方案 在developer.apple.com上显示了

我需要一种在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会接受它,我也不确定如何调用函数以及传递什么值,等等。我在顶部包含了“导入安全性”,所以这不是问题所在

这件事竟如此艰难,真可笑。我只想生成一个非对称密钥对

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

我使用Swift是因为我讨厌objective C。Swift是我最终投入IOS开发的原因

我不知道如何将Objective C类与Swift集成,如果有一个纯Swift解决方案的话,我更希望有一个纯Swift解决方案。如果不是的话,我希望能得到一些关于如何集成一个目标C解决方案并使其工作的建议

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

似乎就是你要找的。它易于使用,可以创建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
    }
}

在GitHub的项目中,有一个很好的例子说明了如何在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
        }
let tagPublic=“com.example.public”
让tagPrivate=“com.example.private”
let publicKeyParameters:[字符串:AnyObject]=[
字符串(kSecAttrIsPermanent):kCFBooleanTrue,
字符串(kSecAttrApplicationTag):tagPublic作为任何对象,
字符串(kSecAttrAccessible):ksecattraccessibleallways
]
var privateKeyParameters:[字符串:AnyObject]=[
字符串(kSecAttrIsPermanent):kCFBooleanTrue,
String(kSecAttrApplicationTag):tagPrivate作为AnyObject,
字符串(kSecAttrAccessible):ksecattraccessibleallways
]
//在此定义要生成的键的类型
变量参数:[字符串:AnyObject]=[
字符串(kSecAttrKeyType):kSecAttrKeyTypeRSA,
字符串(kSecAttrKeySizeInBits):2048,
字符串(kSecReturnRef):kCFBooleanTrue,
kSecPublicKeyAttrs作为字符串:publicKeyParameters作为任何对象,
kSecPrivateKeyAttrs作为字符串:privateKeyParameters作为任何对象,
]
//使用Apple Security Framework生成密钥,并将其保存到应用程序密钥链
var错误:非托管?
让privateKey=SecKeyCreateRandomKey(参数为CFDictionary,&error)
如果privateKey==nil{
打印(“创建键时出错:\(错误!.takeRetainedValue()为错误),未创建键”)
返回
}
//获取生成的公钥
let query:[字符串:AnyObject]=[
字符串(kSecClass):kSecClassKey,
字符串(kSecAttrKeyType):kSecAttrKeyTypeRSA,
字符串(kSecAttrApplicationTag):tagPublic作为任何对象,
字符串(kSecReturnRef):kCFBooleanTrue
]
var publicKeyReturn:AnyObject?
让result=SecItemCopyMatching(查询为CFDictionary,&publicKeyReturn)
如果有结果!=成功{
打印(“从密钥链获取公钥时出错:\(结果)”)
返回
}
让publicKey=publicKey返回为!秘书?
//设置块大小
让keyBlockSize=SecKeyGetBlockSize(self.publicKey!)
//要求keychain以位为单位提供公钥
let query:[字符串:AnyObject]=[
字符串(kSecClass):kSecClassKey,
字符串(kSecAttrKeyType):keyAlgorithm.secKeyAttrType,
字符串(kSecAttrApplicationTag):tagPublic作为任何对象,
字符串(kSecReturnData):kCFBooleanTrue
]
var tempPublicKeyBits:任何对象?
_=SecItemCopyMatching(查询为CFDictionary和tempPublicKeyBits)
guard let publicKeyBits=tempPublicKeyBits as?其他数据{
返回
}

有关从Swift调用SecKeyGeneratePair()的示例,请参见我对的回答。它不是一个异步对,但应该可以让您实现。“异步”只是意味着调用在后台运行,并在完成时调用回调以返回密钥对,而SecKeyGeneratePair在运行的线程中执行并返回密钥。钥匙是一样的。我知道这是一个迟到的答复。但仍在寻找此信息的人,请参考我所知的,Heimdall使用RSA做所有事情,除了生成密钥对,这是帖子所问的。@OgreCodes Heimdall确实生成密钥对。