Search code examples
iosswiftcurvecryptecdh

swift Generate shared key using ECDH


I am trying to encrypt a message to the server. To do this, I generate a public and private key. I send my public key to the server and receive its public key from it.

func generatePair() {
    if let crypto = GMEllipticCurveCrypto.generateKeyPair(for: GMEllipticCurveSecp256r1) {
        crypto.compressedPublicKey = false
        curveCrypto = crypto
        if let publicKey = crypto.publicKey {
            let pub = Data(publicKey[1...publicKey.count-1])
            self.publicKey = pub.base64EncodedString()
            self.privateKey = crypto.privateKeyBase64
        }
    }
}

Upon receipt, I try to generate a shared key to encrypt the data.

func generateSecret(withKey key: String) {
    guard let crypto = curveCrypto else {
        return
    }
    print("generateSecret \(key)")
    sharedKey = crypto.sharedSecret(forPublicKeyBase64: key)
}

But I get the error in line (sharedKey = crypto.sharedSecret(forPublicKeyBase64: key))

*** Terminating app due to uncaught exception 'Invalid Key', reason: 'Public key {length = 64, bytes = 0xace3000d e1483ed9 82d88432 9397c716 ... d64e0fe1 47920d9f } is invalid'

My public key and server key are the same length.

What is I doing wrong?


Solution

  • Finally I have found the solution.

    After receiving public key from server I should do this:

    private func getPublicKey(publicKey: String) -> String? {
        if let publicKeyData = Data(base64Encoded: publicKey) {
            var newKeyData = publicKeyData
            newKeyData.insert(0x04, at: 0)
            if let compressKeyData = curveCrypto?.compressPublicKey(newKeyData) {
                return compressKeyData.base64EncodedString()
            } else {
                print("PUB KEY ERROR: compressKeyData")
                return nil
            }
        } else {
            print("PUB KEY ERROR: b64")
            return nil
        }
    }
    

    And this public key should be used for generation shared key.