Deffie Hellman exchange for ECDH

I am trying to generate public and private keys for an ECDH handshake. Back end is using p256 for public key. I am getting a failed request with status 0

public func makeHandShake(completion: @escaping (Bool, String?) -> ()) {

    guard let config = self.config else { completion(false,APP_CONFIG_ERROR)
        return
    }
    
    var rData = HandshakeRequestTwo()
    let sessionValue = AppUtils().generateSessionID()
    rData.session = sessionValue
    
    //generating my ECDH Key Pair
    let sPrivateKey = P256.KeyAgreement.PrivateKey()
    let sPublicKey = sPrivateKey.publicKey
    
    let privateKeyBase64 = sPrivateKey.rawRepresentation.base64EncodedString()
    print("My Private Key (Base64): \(privateKeyBase64)")
    
    let publicKeyBase64 = sPublicKey.rawRepresentation.base64EncodedString()
    print("My Public Key (Base64): \(publicKeyBase64)")
    
    
    rData.value = sPublicKey.rawRepresentation.base64EncodedString()
    let encoder = JSONEncoder()
    
    do {
        let jsonData = try encoder.encode(rData)
        
        if let jsonString = String(data: jsonData, encoding: .utf8) {
            print("Request Payload: \(jsonString)")
        }
    } catch {
        print("Error encoding request model to JSON: \(error)")
        
        completion(false, "Error encoding request model")
        return
    }
    
    self.rsaReqResponseHandler(config: config, endpoint: config.services.handShake.endpoint, model: rData) { resToDecode, error in
        
        print("Response received before guard : \(resToDecode ?? "No response")")
        
        guard let responseString = resToDecode else {
            print("response string is nil")
            
            completion(false,error)
            return
        }
        print("response received: \(responseString)")
        let decoder = JSONDecoder()
        
        do {
            
            let request = try decoder.decode(DefaultResponseTwo.self, from: Data(responseString.utf8))
            let msg = request.message
            let status = request.status == 1 ? true : false
            completion(status,msg)
            
            guard let serverPublicKeyBase64 = request.data?.value else {
                print("Server response is missing the value")
                completion(false, config.messages.serviceError)
                return
            }

            print("Server Public Key (Base64): \(serverPublicKeyBase64)")

            
            if serverPublicKeyBase64.isEmpty {
                print("Server public key is an empty string.")
                completion(false, config.messages.serviceError)
                return
            }
            
            guard let serverPublicKeyData = Data(base64Encoded: serverPublicKeyBase64) else {
                print("Failed to decode server public key from Base64. Data is invalid.")
                completion(false, config.messages.serviceError)
                return
            }
            
            print("Decoded server public key data: \(serverPublicKeyData)")
            
            guard let serverPublicKey = try? P256.KeyAgreement.PublicKey(rawRepresentation: serverPublicKeyData) else {
                print("Decoded server public key data is invalid for P-256 format.")
                completion(false, config.messages.serviceError)
                return
            }
        
            // Derive Shared Secret and AES Key
            let sSharedSecret = try sPrivateKey.sharedSecretFromKeyAgreement(with: serverPublicKey)
            
            // Derive AES Key from Shared Secret
            let symmetricKey = sSharedSecret.hkdfDerivedSymmetricKey(
                using: SHA256.self,
                salt: "AES".data(using: .utf8) ?? Data(),
                sharedInfo: Data(),
                outputByteCount: 32
            )
            
            //  Storing AES Key in Config
            let symmetricKeyBase64 = symmetricKey.withUnsafeBytes { Data($0) }.base64EncodedString()
            
            print("Derived Key: \(symmetricKeyBase64)")
            
            self.config?.cryptoConfig.key = symmetricKeyBase64
            
            AppUtils.Log(from: self, with: "Handshake Successful, AES Key Established")
            
        } catch {
            AppUtils.Log(from: self, with: "Handshake Failed :: \(error)")
            completion(false, self.config?.messages.serviceError)
        }
    }
}   this is request struct model public struct HandshakeRequestTwo: Codable {
public var session: String?
public var value: String?

public enum CodingKeys: CodingKey {
    case session
    case value
}

public init(session: String? = nil, value: String? = nil) {
    self.session = session
    self.value = value
}

} This is backend's response {"message":"Success","status":1,"data":{"senderId":"POSTBANK","value":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErLxbfQzX+xnYVT1LLP5VOKtkMRVPRCoqYHcCRTM64EMEOaRU16yzsN+2PZMJc0HpdKNegJQZMmswZtg6U9JGVw=="}} This is my response struct model public struct DefaultResponseTwo: Codable { public var message: String? public var status: Int? public var data: HandshakeData?

public init(message: String? = nil, status: Int? = nil, data: HandshakeData? = nil) {
    self.message = message
    self.status = status
    self.data = data
}

}

public struct HandshakeData: Codable { public var senderId: String? public var value: String?

public init(senderId: String? = nil, value: String? = nil) {
    self.senderId = senderId
    self.value = value
}

}

I am getting a failed request with status 0

From which API? Or is this from your back end?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

status 0 is from back end. if status is 0 it's a fail, when status is 1 it's a success

status 0 is from back end.

OK.

I’ll come back to that in a sec, but first I want to clarify one point. In your first post you wrote:

I am getting a failed request with status 0

and you also wrote:

This is backend's response {"message":"Success","status":1,…

This seems to be contradictory, that is, the status in the second quote is 1, not 0.


But as to how you debug this in general, if you send something to your back end and it responds with a ‘failed’ status, it’s hard to debug that on the client. You need to talk to your back-end folks to see if there’s a way for them to provide you with more info as to why the thing you sent is incorrect.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Deffie Hellman exchange for ECDH
 
 
Q