我需要一种在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解决方案并使其工作的一些指示。
以上代码段是Apple提供的唯一函数调用,当然它不完整,没有意义,也不起作用。
答案 0 :(得分:2)
在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
}
答案 1 :(得分:1)
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
}
}