Обычным способом будет SSL, как уже говорилось.Это поддерживает (обязательную) аутентификацию и шифрование сервера по умолчанию, аутентификация клиента является необязательной (например, в зависимости от конфигурации - сервер может убедиться, что клиенты аутентифицированы).
В Java вы можете использовать SSLSocket (и SSLServerSocket)(или соответствующие фабричные классы), или SSLEngine (если вы хотите сделать неблокирующий ввод-вывод).Или какой-то API более высокого уровня, который использует это под прикрытием.
Другой вариант - протокол SSH .Это позволяет зашифрованное и (обычно) аутентифицированное соединение с обеих сторон, по которому можно маршрутизировать несколько каналов .Это обычно используется для удаленного выполнения команд или передачи файлов, но также позволяет переадресацию портов.
В Java это может быть реализовано (на стороне клиента), например, JSch .Я не знаю ни одной реализации Java на стороне сервера, но вы можете использовать обычный сервер OpenSSH и перенаправить порты на ваш процесс Java-сервера.