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

我需要一种在Swift中生成RSA非对称密钥对的方法。 我不需要把它存储在钥匙链或任何东西。 我只需要生成一个密钥对,并将两个键都转换为stringvariables。

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

该公钥将在稍后由Web服务使用,以encryption值为IOS应用程序的一次性密码和其他敏感值。 我将为从IOS应用程序stream向Web服务的小部分数据实现类似的scheme。

我可以在developer.apple.com上看到唯一logging的在Swift中生成密钥对的API声明:

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解决scheme。 如果没有,我会很感激有关如何整合Objective C解决scheme并使其工作的一些指示。

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

请帮助,如果你可以…这将不胜感激。 :) 谢谢

– =卡梅伦

Heimdall似乎是你在找什么。 它易于使用,可以创buildRSA密钥对,进行encryption,解密,签名和validation。

它使用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 } } 

我不太熟悉这个问题的快速解决scheme,但是关于swift的很酷的事情是,在objective-c中所做的一切仍然适用于基于快速的项目。

为了执行RSAencryption,我使用了在下面的链接提到的接近:

http://jslim.net/blog/2013/01/05/rsa-encryption-in-ios-and-decrypt-it-using-php/

基本上,作者创build了一个苹果的安全框架类的包装,所以你只能专注于encryption。 此外,您可以按照以下方式修改初始化方法,以获取公钥长度和数据/公钥关键字path作为参数:

 - (id)initWithData:(NSData *)keyData publicKeyLength:(int) publicKeyLength { self = [super init]; if (self) { if (keyData == nil) { return nil; } certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef) keyData); if (certificate == nil) { NSLog(@"Can not read certificate from data"); return nil; } policy = SecPolicyCreateBasicX509(); OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust); if (returnCode != 0) { NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %d", (int)returnCode); return nil; } SecTrustResultType trustResultType; returnCode = SecTrustEvaluate(trust, &trustResultType); if (returnCode != 0) { return nil; } publicKey = SecTrustCopyPublicKey(trust); if (publicKey == nil) { NSLog(@"SecTrustCopyPublicKey fail"); return nil; } maxPlainLen = SecKeyGetBlockSize(publicKey) - 12; self.publicKeyLength = publicKeyLength; } return self; } - (id)initWithPublicKeyPath:(NSString *)publicKeyPath publicKeyLength:(int) publicKeyLength { if (publicKeyPath == nil) { NSLog(@"Can not find %@", publicKeyPath); return nil; } NSData *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath]; return [self initWithData:publicKeyFileContent publicKeyLength:publicKeyLength]; } 

这些类可以通过swift使用,只需将文件添加到项目和头文件到Bridging-Header.h中即可。 在这之后,你在swift上使用这个类:

 let rsa = RSA(publicKeyPath: "public_key.der",publicKeyLength: 256); rsa.encryptToString("stringToEncrypt") 

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