title: Exporting SecKey from iOS to watchOS
body: <p>I am trying to sync up private asymmetric keys between my iOS app and its watchOS equivalent.  I have tried using <code>SecKeyCopyExternalRepresentation</code> to export it out as <code>CFData</code> and then send it to the watch using <code>WatchConnectivity</code>.  However when it gets to the watch I have no way of converting the Data back into a <code>SecKey</code>.  I tried using <code>SecKeyCreateWithData</code> in an attempt to recreate it, but it seems that that only works with symmetric keys, for when I tried it it crashed the watch app.  Any ideas?</p>
  
  <p>iOS Code:</p>
  
  <pre><code>func sendSharedKeyPair(keyPair: (publicKey: SecKey, privateKey: SecKey)) {
      var error: Unmanaged&lt;CFError&gt;?
  
      let publicKeyData = SecKeyCopyExternalRepresentation(keyPair.publicKey, &amp;error)
      if let error = error {
          return print("Error sending shared key: \(error)")
      }
      let privateKeyData = SecKeyCopyExternalRepresentation(keyPair.privateKey, &amp;error)
      if let error = error {
          return print("Error sending shared key: \(error)")
      }
  
      if let publicKeyData = publicKeyData, let privateKeyData = privateKeyData {
          session.sendMessage(["requestedCommand": WatchControllerCommands.sendSharedKeyPair.rawValue, "keyPair": ["publicKey": publicKeyData, "privateKey": privateKeyData]], replyHandler: nil, errorHandler: { error in
              print(error)
          })
      }
  
  
  }
  </code></pre>
  
  <p>watchOS Code:</p>
  
  <pre><code>func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
      guard let requestedCommand = (message["requestedCommand"] as? String).flatMap({ WatchControllerCommands(rawValue: $0) }), requestedCommand == .sendSharedKeyPair else { return }
  
      guard let publicKeyData = (message["keyPair"] as? [String: Any])?["publicKey"].flatMap({ $0 as? Data }), let privateKeyData = (message["keyPair"] as? [String: Any])?["privateKey"].flatMap({ $0 as? Data }) else { return print("Couldn't parse keys") }
  
      let publicTag = "myAppTag"
      let privateTag = publicTag + ".private"
  
      let privateAttributes = [String(kSecAttrIsPermanent): true,
                               String(kSecAttrApplicationTag): privateTag] as [String : Any]
      let publicAttributes = [String(kSecAttrIsPermanent): true,
                              String(kSecAttrApplicationTag): publicTag] as [String : Any]
  
      var error: Unmanaged&lt;CFError&gt;?
      let publicCFData = publicKeyData as CFData
      let privateCFData = privateKeyData as CFData
      let publicCFDict = publicAttributes as CFDictionary
      let privateCFDict = privateAttributes as CFDictionary
      SecKeyCreateWithData(publicCFData, publicCFDict, &amp;error)
      if let error = error {
          print(error)
      }
      SecKeyCreateWithData(privateCFData, privateCFDict, &amp;error)
      if let error = error {
          print(error)
      }
  }
  </code></pre>