2016-05-04 13 views
0

Verwenden von Swift 2.2; Xcode 7.3.1 unter El CapitanExportieren eines von SecKeyGeneratePair generierten öffentlichen Schlüssels mit SecItemCopyMatching swift 2.0

Erstellt ein privates/öffentliches Schlüsselpaar mit SecKeyGeneratePair Habe eine Kopie meines öffentlichen Schlüssels mit diesem Code ... den ich dann verschlüsseln, so dass ich es über eine Bluetooth-Verbindung senden kann.

internal func generateKeyPair(publicKeyTag: String, privateKeyTag:String, keySize: Int) { 

    let privateKeyAttr: [NSString: AnyObject] = [ 
     kSecAttrIsPermanent: true, 
     kSecAttrApplicationTag: privateKeyTag.dataUsingEncoding(NSUTF8StringEncoding)! 
    ] 
    let publicKeyAttr: [NSString: AnyObject] = [ 
     kSecAttrIsPermanent: true, 
     kSecAttrApplicationTag: publicKeyTag.dataUsingEncoding(NSUTF8StringEncoding)! 
    ] 
    let parameters: [NSString: AnyObject] = [ 
     kSecAttrKeyType: kSecAttrKeyTypeRSA, 
     kSecAttrKeySizeInBits: keySize, 
     kSecPrivateKeyAttrs: privateKeyAttr, 
     kSecPublicKeyAttrs: publicKeyAttr 
    ] 

    let result = SecKeyGeneratePair(parameters, &publicKey, &privateKey) 

    if errSecSuccess != result { 
     print("generateKeyPair fail",errSecSuccess, result) 
    } else { 
     //print("\(publicKey)\n\n","\(privateKey)") 

    var dataPtr: AnyObject? 
    let query: [NSString:AnyObject] = [ 
     kSecClass: kSecClassKey, 
     kSecAttrApplicationTag: publicKeyTag.dataUsingEncoding(NSUTF8StringEncoding)!, 
     kSecReturnData: true 
    ] 
    let qResult = SecItemCopyMatching(query, &dataPtr) 
    if (qResult == errSecSuccess) { 
     let PublicKeyText = dataPtr as? NSData 
     base64Encoded = PublicKeyText!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) 
     print("PublicKeyText \(base64Encoded)") 
    } 
    } 
} 

Jetzt kann ich meine base64EncodedString Blob mit diesem Code uncodiert ...

let data = NSData(base64EncodedString: superString8, options: NSDataBase64DecodingOptions(rawValue:0)) 

Aber wie man es wieder zu einem brauchbaren SecKey Objekt mit Swift? Ich diese Referenz gefunden und begann, es zu übersetzen ; aber ich fürchte, ich bin hier weit von meiner Tiefe entfernt?

get SecKeyRef from base64 coded string

Das ist, was ich bisher ..

 let cert:SecCertificateRef! 
      let policy:SecPolicyRef! 
      cert = SecCertificateCreateWithData(kCFAllocatorDefault, data!) 
      policy = SecPolicyCreateBasicX509(); 
      //var status:OSStatus! 
      var publicKey: SecKeyRef! 
      //var publicKeyPtr = withUnsafeMutablePointer(&publicKey, { $0 }) 
      var trust:SecTrust? 
      let trustPtr = withUnsafeMutablePointer(&trust , { $0}) 
      var certArray:[SecCertificateRef] = [] 
      certArray.append(cert) 

      var unsafeVariable:UnsafePointer<Void> 

      let certArrayPtr = withUnsafeMutablePointer(&unsafeVariable, {$0}) 
      var newTrustType: SecTrustResultType = UInt32(kSecTrustResultInvalid) 
      let newTrustTypePtr = withUnsafeMutablePointer(&newTrustType, {$0}) 

      if (cert != nil) { 
       //certArray[1] = {cert}() 
       // let certs:[SecCertificateRef] = CFArrayCreate(kCFAllocatorDefault, certArrayPtr, 1, nil) as! [SecCertificateRef] 
       let certs:[SecCertificateRef] = CFArrayCreate(kCFAllocatorDefault, certArrayPtr, 1, nil) as! [SecCertificateRef] 
       var status = SecTrustCreateWithCertificates(certs, policy, trustPtr) 
       if (status == errSecSuccess){ 
        //status = SecTrustEvaluate(trust!, trustTypePtr) 
         status = SecTrustEvaluate(trust!, newTrustTypePtr) 
        // Evaulate the trust. 
        switch (Int(newTrustType)) { 
        case kSecTrustResultInvalid: break 
        case kSecTrustResultDeny: break 
        case kSecTrustResultUnspecified: break 
        case kSecTrustResultFatalTrustFailure: break 
        case kSecTrustResultOtherError: break 
        case kSecTrustResultRecoverableTrustFailure: 
         publicKey = SecTrustCopyPublicKey(trust!); 
         break; 
        case kSecTrustResultProceed: 
         publicKey = SecTrustCopyPublicKey(trust!); 
         break; 
        } 

       } 
      } 
     } else { 
      superString8 = superString8 + stringFromData! 
     } 
    } 

enter image description here

+0

In welcher Zeile Ihres Codes kommt dieser Fehler, auch in Ihrem Screenshot, Ihre Fehlermeldung lautet trunca ... –

+0

Die angezeigte Fehlermeldung kommt von der Zeile, die CertArrayPtr definiert ... – user3069232

Antwort

1

Versuchen Sie so etwas wie dies geschafft:

let certArrayPtr = withUnsafeMutablePointer(&certArray, {$0}) 
    var newTrustType: SecTrustResultType = UInt32(kSecTrustResultInvalid) 
    let newTrustTypePtr = withUnsafeMutablePointer(&newTrustType, {$0}) 

    if (cert != nil) { 
     certArray[1] = {cert}() 
     let certs = CFArrayCreate(kCFAllocatorDefault, unsafeBitCast(certArrayPtr, UnsafeMutablePointer<UnsafePointer<Void>>.self), 1, nil) as! [SecCertificateRef] 

(das erste und das letzte Mal hier Linien anders ... keine Notwendigkeit für certArrayPtr zu sein a var und unsafeBitCast ist grob, aber es sollte Sie über Ihre Hürde bekommen; Ich fand es in this related question).

+0

Wow, ein schnelles DANKE; es kompiliert, jetzt für den Säuretest funktioniert es !! – user3069232

+0

Michael, gewählt, weil es kompiliert; aber leider funktioniert das nicht. Es scheint, dass SeccertificateCreateWithData nichts erstellt, es gibt nur eine Null zurück. Den Code zurück zu dem Client portieren, der den öffentlichen Schlüssel sendet, um die Bluetooth base64 Konversation und Übertragung auszuschließen. – user3069232