주로 사용되는 jdk 8과 11의 2021년 4월 20일 releaseNote이다.

Java™ SE Development Kit 11, 11.0.11 Release Notes

Java™ SE Development Kit 8, Update 291 Release Notes

TLS 1.0과 TLS 1.1이 disable 되었다는 내용이 포함되어 있다.

아래 코드는 OkHttp의 RealConnection에서 tls를 연결 하는 메소드이다.

private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
  Address address = route.address();
  SSLSocketFactory sslSocketFactory = address.sslSocketFactory();
  boolean success = false;
  SSLSocket sslSocket = null;
  try {
    // Create the wrapper over the connected socket.
    sslSocket = (SSLSocket) sslSocketFactory.createSocket(
        rawSocket, address.url().host(), address.url().port(), true /* autoClose */);

    // Configure the socket's ciphers, TLS versions, and extensions.
    ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
    if (connectionSpec.supportsTlsExtensions()) {
      Platform.get().configureTlsExtensions(
          sslSocket, address.url().host(), address.protocols());
    }

    // Force handshake. This can throw!
    sslSocket.startHandshake();
    // block for session establishment
    SSLSession sslSocketSession = sslSocket.getSession();
    Handshake unverifiedHandshake = Handshake.get(sslSocketSession);

    // Verify that the socket's certificates are acceptable for the target host.
    if (!address.hostnameVerifier().verify(address.url().host(), sslSocketSession)) {
      List<Certificate> peerCertificates = unverifiedHandshake.peerCertificates();
      if (!peerCertificates.isEmpty()) {
        X509Certificate cert = (X509Certificate) peerCertificates.get(0);
        throw new SSLPeerUnverifiedException(
            "Hostname " + address.url().host() + " not verified:"
                + "\\n    certificate: " + CertificatePinner.pin(cert)
                + "\\n    DN: " + cert.getSubjectDN().getName()
                + "\\n    subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(cert));
      } else {
        throw new SSLPeerUnverifiedException(
            "Hostname " + address.url().host() + " not verified (no certificates)");
      }
    }

    // Check that the certificate pinner is satisfied by the certificates presented.
    address.certificatePinner().check(address.url().host(),
        unverifiedHandshake.peerCertificates());

    // Success! Save the handshake and the ALPN protocol.
    String maybeProtocol = connectionSpec.supportsTlsExtensions()
        ? Platform.get().getSelectedProtocol(sslSocket)
        : null;
    socket = sslSocket;
    source = Okio.buffer(Okio.source(socket));
    sink = Okio.buffer(Okio.sink(socket));
    handshake = unverifiedHandshake;
    protocol = maybeProtocol != null
        ? Protocol.get(maybeProtocol)
        : Protocol.HTTP_1_1;
    success = true;
  } catch (AssertionError e) {
    if (Util.isAndroidGetsocknameError(e)) throw new IOException(e);
    throw e;
  } finally {
    if (sslSocket != null) {
      Platform.get().afterHandshake(sslSocket);
    }
    if (!success) {
closeQuietly(sslSocket);
    }
  }
}

위 코드 중 우리가 볼 코드는 아래 코드이다.

ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);

코드를 파고 들어가면 SSLSocket에서 지원하는 tls 버전들을 배열에 넣게 된다.

위 코드 중 connectionSpecs 필드값을 디버그 모드로 출력한 내용들이다. TLS1.0 부터 TLS 1.3까지 사용 가능하도록 설정해 주었기에 아래서 확인할 수 있다.

이 값들을 isCompatible 메소드로 비교를 하게되는데 아래 코드가 isCompatble 메소드이다.