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?
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.