2015-10-05 88 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