2015-10-05 56 views
2

创建密钥对的函数(私有,公共)生成与SWIFT 2.0

public func generateKeyPair(publicKeyTag: String, privateKeyTag:String, keySize: Int) -> KeyPair? { 

    let privateKeyAttr: [String: AnyObject] = [ 
     kSecAttrIsPermanent as String: kCFBooleanTrue, 
     kSecAttrApplicationTag as String: privateKeyTag 
    ]; 

    let publicKeyAttr: [String: AnyObject] = [ 
     kSecAttrIsPermanent as String: kCFBooleanTrue, 
     kSecAttrApplicationTag as String: publicKeyTag 
    ]; 

    let keyPairAttr: [String: AnyObject] = [ 
     kSecAttrKeyType as! String: kSecAttrKeyTypeRSA, 
     kSecAttrKeySizeInBits as! String: keySize, 
     kSecPrivateKeyAttrs as! String: privateKeyAttr, 
     kSecPublicKeyAttrs as! String: publicKeyAttr 
    ]; 

    var publicKeyPtr, privateKeyPtr: Unmanaged<SecKey>?; 

    let error = SecKeyGeneratePair(keyPairAttr, &publicKeyPtr, &privateKeyPtr) 

    if(result != errSecSuccess){ 
     return nil 
    } 

    let publicKey = publicKeyPtr!.takeRetainedValue() 
    let privateKey = privateKeyPtr!.takeRetainedValue() 
    return KeyPair(publicKey: publicKey, privateKey: privateKey) 
} 

提高

Cannot convert value of type 'inout Unmanged<SecKey>?' ... expected argument type 'UnsafeMutablePointer<SecKey?> ...' 

这听起来sound当我仰望the api for SecKeyGeneratePair所以让我们改变的类型钥匙扣关键publicKeyPtr, privateKeyPtr

public func generateKeyPair(publicKeyTag: String, privateKeyTag:String, keySize: Int) -> KeyPair ? { 

    let privateKeyAttr: [String: AnyObject] = [ 
     kSecAttrIsPermanent as String: kCFBooleanTrue, 
     kSecAttrApplicationTag as String: privateKeyTag 
    ] 

    let publicKeyAttr: [String: AnyObject] = [ 
     kSecAttrIsPermanent as String: kCFBooleanTrue, 
     kSecAttrApplicationTag as String: publicKeyTag 
    ] 

    let parameters: [String: AnyObject] = [ 
     kSecAttrKeyType as String: kSecAttrKeyTypeRSA, 
     kSecAttrKeySizeInBits as String: keySize, 
     kSecPrivateKeyAttrs as String: privateKeyAttr, 
     kSecPublicKeyAttrs as String: publicKeyAttr 
    ] 

    var publicKeyPtr: UnsafeMutablePointer<SecKey?> = nil 
    var privateKeyPtr: UnsafeMutablePointer<SecKey?> = nil 

    let result = SecKeyGeneratePair(parameters, publicKeyPtr, privateKeyPtr) 

    if(result != errSecSuccess){ 
     return nil 
    } 

    let publicKey = Unmanaged<SecKey>.fromOpaque(COpaquePointer(publicKeyPtr)).takeRetainedValue() 
    let privateKey = Unmanaged<SecKey>.fromOpaque(COpaquePointer(privateKeyPtr)).takeRetainedValue() 

    publicKeyPtr.destroy() 
    privateKeyPtr.destroy() 

    return KeyPair(publicKey: publicKey, privateKey: privateKey) 
} 

但是当我使用的功能ñ公钥和专用密钥提出:

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, ... 

,当我插入一个断点,我意识到,指针(`publicKeyPtr,privateKeyPtr)永远不会置。

那么如何将swift 1.2代码迁移到swift 2.0?

回答

2

尝试:

public func generateKeyPair(publicKeyTag: String, privateKeyTag:String, keySize: Int) -> KeyPair? { 

    let privateKeyAttr: [NSString: AnyObject] = [ 
     kSecAttrIsPermanent: true, 
     kSecAttrApplicationTag: privateKeyTag 
    ] 
    let publicKeyAttr: [NSString: AnyObject] = [ 
     kSecAttrIsPermanent: true, 
     kSecAttrApplicationTag: publicKeyTag 
    ] 
    let parameters: [NSString: AnyObject] = [ 
     kSecAttrKeyType: kSecAttrKeyTypeRSA, 
     kSecAttrKeySizeInBits: keySize, 
     kSecPrivateKeyAttrs: privateKeyAttr, 
     kSecPublicKeyAttrs: publicKeyAttr 
    ] 

    var publicKey: SecKey? 
    var privateKey: SecKey? 
    let result = SecKeyGeneratePair(parameters, &publicKey, &privateKey) 

    if result != errSecSuccess { 
     return nil 
    } 
    return KeyPair(publicKey: publicKey!, privateKey: privateKey!) 
} 

您可以传递出&表达式UnsafeMutablePointer参数。

另请参阅:swift 2.0 keychain type errors for SecItemCopyMatching

+0

该代码的作品(tm)和解释有助于med thx! – pellekrogholt

+0

“kSecAttrApplicationTag”不应该是“NSData”吗?此代码编译但崩溃。 – Sulthan