title: Encryption in swift using Diffie Hellman key exchange and an elliptic curve encryption
body: <p>I've been trying to encrypt and decrypt a string in swift using a Diffie Hellman key exchange and an elliptic curve encryption. </p>
  
  <p>Following is the code that I followed.</p>
  
  <p>SWIFT Code :</p>
  
  <pre><code> let attributes: [String: Any] = [kSecAttrKeySizeInBits as String: 256,
                                       kSecAttrKeyType as String: kSecAttrKeyTypeEC,
                                       kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: false]]
   var error: Unmanaged&lt;CFError&gt;?
   if #available(iOS 10.0, *) {
   **// Step 1:  Generating the Public &amp; Private Key**
          guard let privateKey1 = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;error) else {return false}
  
          let publicKey1 = SecKeyCopyPublicKey(privateKey1)
          guard let privateKey2 = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;error) else {return false}
  
          let publicKey2 = SecKeyCopyPublicKey(privateKey2)
  
          let dict: [String: Any] = [:]
   **// Step 2:  Generating Shared Key**   
          guard let shared1 = SecKeyCopyKeyExchangeResult(privateKey1, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey2!, dict as CFDictionary, &amp;error) else {return false}
  
  **// Step 3:  Encrypt string using Sharedkey**
          let options: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeEC,
                                        kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
                                        kSecAttrKeySizeInBits as String : 256]
          // Stuck from this line on
          guard let key = SecKeyCreateWithData(shared1 ,
                                               options as CFDictionary,
                                               &amp;error) else {return false}
          print(key)
  
  
          let str = "Hello"
          let byteStr: [UInt8] = Array(str.utf8)
          let cfData = CFDataCreate(nil, byteStr, byteStr.count)
  
  
          guard let encrypted = SecKeyCreateEncryptedData(publicKey1!,
                                                          SecKeyAlgorithm.ecdsaSignatureDigestX962SHA256,
                                                          cfData!,
                                                          &amp;error) else {return false}
          print(encrypted)
  
      } else {
          print("unsupported")
      }
  </code></pre>
  
  <p>JAVA Code :</p>
  
  <pre><code>public static Map&lt;String, Object&gt; ecEncrypt(String deviceData, String serverPubKey, String dsTranID)
  throws DataEncryptionException {
  provider = new BouncyCastleProvider();
  HashMap&lt;String, Object&gt; result = null;
  JWEObject jweObject = null;
  JWK jwk = null;
  SecretKey Z = null;
  JWEHeader header = null;
  ECPublicKey ecpubkey = null;
  byte[] byte_pubkey = null;
  
  try {
  
  result = new HashMap&lt;String, Object&gt;();
  /*
   * Generate Ephemeral keypair for SDk which constitute Public and
   * Private key of SDK
   */
  STEP 1:
  sdkKeyPair = Crypto.generateEphemeralKeyPair();
  
  /*
   * Compute Secrete Key Z from SDKs Private Key(pSDK),DS Public
   * key(serverPubKey) and DS ID
   */
  //converting string to Bytes
  STEP 2:
  byte_pubkey = Base64.decode(serverPubKey, android.util.Base64.DEFAULT);
  
  //converting it back to EC public key
  STEP 3:
  KeyFactory factory = KeyFactory.getInstance("ECDSA", provider);
  ecpubkey = (ECPublicKey) factory.generatePublic(new X509EncodedKeySpec(byte_pubkey));
  System.out.println("FINAL OUTPUT" + ecpubkey);
  
  STEP 4:
  Z = Crypto.generateECDHSecret(ecpubkey,
  (ECPrivateKey) sdkKeyPair.getPrivate(), dsTranID,
  "A128CBC_HS256");
  
  System.out.println("****Secrete key Z for SDK Computed succesfully *****");
  /*
   * Build JWK to construct header
   */
  STEP 5:
  jwk = new ECKey.Builder(Curve.P_256,
  (ECPublicKey) sdkKeyPair.getPublic()).build();
  
  STEP 6:
  header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES,
  EncryptionMethod.A128CBC_HS256).ephemeralPublicKey(
  ECKey.parse(jwk.toJSONString())).build();
  
  System.out.println("****Header for SDK Computed  succesfully*****");
  
  /*
   * Add Header and payload before encrypting payload using secret key
   * Z
   */
  
  STEP 7:
  jweObject = new JWEObject(header, new Payload(deviceData));
  jweObject.encrypt(new DirectEncrypter(Z));
  /*
   * serialize JWEobject which contains
   * [header-base64url].[encryptedKey
   * -base64url].[iv-base64url].[cipherText
   * -base64url].[authTag-base64url]
   */
  System.out
  .println("****Payload of SDK encrypted succesfully *****");
  
  return result;
  } catch (Exception e) {
  e.printStackTrace();
  throw new DataEncryptionException();
  } finally {
  sdkKeyPair = null;
  jweObject = null;
  jwk = null;
  Z = null;
  header = null;
  }
  }
  </code></pre>
  
  <p>I included Java code as well. I have to do the same in Swift. How to do EC Encryption using the Shared key(Shared1) to encrypt the string? I need to do Step 3. Anyone please help on this?</p>