Если исходники открыты, то единственный вариант — асимметричное шифрование с публичными ключами.
Клиент и сервер обмениваются публичными ключами, секретные оставляют у себя.
Реализаций много. Одна из возможных:
1. Клиент соединяется с сервером, предоставляет ему свой публичный ключ
2. сервер посылает клиенту вопрос, подписанный публичным ключом клиента
3. клиент используя свой закрытый ключ выясняет вопрос сервера, решает вопрос и подписывает его публичным ключом сервера, передаёт серверу
4. сервер применяет к ответу свой секретный ключ, тем самым снимая шифрование, и проверяет ответ. если всё ок — сервер считает, что клиент подтверждён.
возможно то же самое, но в другую сторону для того, чтоб клиент проверил Сервер