middle
Что такое mTLS и зачем нужна двусторонняя аутентификация?
mTLS (Mutual TLS) — расширение TLS, при котором не только клиент проверяет сертификат сервера, но и сервер проверяет сертификат клиента. Обе стороны аутентифицируют друг друга на уровне транспорта.
Отличие от обычного TLS
| Параметр | TLS | mTLS |
|---|---|---|
| Сервер предъявляет сертификат | Да | Да |
| Клиент предъявляет сертификат | Нет | Да |
| Аутентификация сервера | Да | Да |
| Аутентификация клиента | Нет (другие механизмы) | Да (на уровне TLS) |
Процесс mTLS Handshake
Пример
Клиент Сервер
│──── ClientHello ──────────────────────────────>│
│<─── ServerHello + Certificate ─────────────────│
│<─── CertificateRequest ───────────────────────│ <- сервер запрашивает
│<─── ServerHelloDone ──────────────────────────│ сертификат клиента
│──── Certificate (сертификат клиента) ─────────>│ <- клиент предъявляет
│──── ClientKeyExchange ────────────────────────>│ свой сертификат
│──── CertificateVerify ────────────────────────>│
│──── Finished ─────────────────────────────────>│
│<─── Finished ─────────────────────────────────│
Когда используется mTLS
- Межсервисное взаимодействие — микросервисы аутентифицируют друг друга
- Банковские интеграции — взаимодействие с платёжными системами (SWIFT, НСПК)
- API для партнёров — контрагенты подключаются с использованием клиентских сертификатов
- Service Mesh — Istio/Linkerd автоматически обеспечивают mTLS между подами
Настройка mTLS в Spring Boot
Пример
server:
ssl:
key-store: classpath:server-keystore.p12
key-store-password: ${SSL_KEYSTORE_PASSWORD}
key-store-type: PKCS12
trust-store: classpath:truststore.jks
trust-store-password: ${SSL_TRUSTSTORE_PASSWORD}
client-auth: need # need = обязательно, want = опционально
Настройка RestTemplate для mTLS
Пример Java-кода
@Bean
public RestTemplate restTemplate() throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("client-keystore.p12"),
"password".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("truststore.jks"),
"password".toCharArray());
SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(keyStore, "password".toCharArray())
.loadTrustMaterial(trustStore, null)
.build();
HttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.build();
return new RestTemplateBuilder()
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient))
.build();
}
mTLS является стандартом для критичных интеграций, так как обеспечивает взаимную аутентификацию сторон на уровне транспорта ещё до обработки бизнес-логики.
На собеседовании: интервьюер хочет услышать разницу между TLS и mTLS и знание реальных сценариев применения (межсервисное взаимодействие, Service Mesh). Частая ошибка — не упомянуть
client-auth: needв Spring Boot и не объяснить, зачем нужен TrustStore.