okhttp wiki--HTTPS 학습

3995 단어

HTTPS


OkHttp는 서로 경쟁하는 두 요소의 균형을 맞추려고 합니다.
  • 연결성(Connectivity): 가능한 한 많은 서버에 연결합니다.이것은 최신 버전의boringssl을 실행하는 서버와 유행하지 않는 오래된 버전의 OpenSSL 서버를 포함한다.
  • 연결의 안전성(Security): 원격 웹 서버 인증서 검증과 비밀 데이터 교환에 대한 강력한 암호화를 포함합니다.

  • HTTPS 서버와 연결을 협상할 때, OkHttp는 어떤 TLS 버전(TLS versions)과 암호 세트(cipher suites)를 제공하는지 알아야 한다.연결성을 극대화하고자 하는 클라이언트는 폐기된 TLS 버전과 약한 디자인의 암호 세트를 포함합니다.보안을 극대화하려는 엄격한 클라이언트는 최신 TLS 버전과 가장 강력한 암호 세트만 사용하도록 제한합니다.
    구체적인 안전성 vs 연결성 결정은 ConnectionSpec에 의해 이루어진다.OkHttp에는 다음과 같은 세 가지 기본 접속 정책이 포함되어 있습니다.
  • MODERN_TLS는 최신 HTTPS 서버에 연결하는 보안 구성입니다.
  • COMPATIBEL_TLS는 오래된 HTTPS 서버에 연결하는 보안 구성입니다.
  • CLEARTEXT는 http://시작 URL의 비보안 구성입니다.

  • 기본적으로 OkHttp는 현재 구성에 실패하면 MODERN_TLS 연결로 되돌아갑니다.
    각 접속 정책에서 특정 TLS 버전 및 암호 세트는 각 버전에서 변경될 수 있습니다.예를 들어 OkHttp2.2에서 우리는 POODLE 공격에 대응하기 위해 SSL 3.0을 사용하지 않았다.Ok Http2.3에서 RC4를 비활성화했습니다.데스크톱 웹 브라우저와 마찬가지로 최신 OkHttp 버전을 사용하는 것이 안전을 확보하는 가장 좋은 방법입니다.
    사용자 정의 TLS 버전과 암호 세트를 사용하여 연결 정책을 설정할 수 있습니다.예를 들어 아래의 설정은 세 가지 중시되는 암호 세트로 제한되어 있다.그것의 결함은 안드로이드 5.0 이상과 상응하는 새로운 웹 서버가 필요하다는 것이다.
    ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)  
        .tlsVersions(TlsVersion.TLS_1_2)
        .cipherSuites(
              CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
              CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
              CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
        .build();
    
    OkHttpClient client = ...
    client.setConnectionSpecs(Collections.singletonList(spec));

    인증서 잠금(Certificate Pinning)


    기본적으로 OkHttp는 플랫폼에서 지원하는 인증서 발급 기관을 신뢰합니다.이런 전략은 연결성을 극대화시켰지만 인증 기구에 대한 공격의 제약을 받았다. 예를 들어 2011년의 DigiNotar 공격이다.그것 또한 당신의 HTTPS 서버의 인증서가 인증서 발급 기구에서 서명한 것이라고 가정합니다.
    CertificatePinner를 사용하여 신뢰할 수 있는 인증 기관을 구속합니다.인증서 잠금은 보안을 강화하지만 서버 팀이 TLS 인증서를 업그레이드하는 능력을 제한합니다.서버 TLS 관리자의 축복이 없습니다. 인증서 잠금을 사용하지 마십시오!
      public CertificatePinning() {
        client = new OkHttpClient();
        client.setCertificatePinner(
            new CertificatePinner.Builder()
                .add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
                .add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
                .add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
                .add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
                .build());
      }
    
      public void run() throws Exception {
        Request request = new Request.Builder()
            .url("https://publicobject.com/robots.txt")
            .build();
    
        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    
        for (Certificate certificate : response.handshake().peerCertificates()) {
          System.out.println(CertificatePinner.pin(certificate));
        }
      }

    신뢰할 수 있는 인증서 사용자 정의


    완전한 코드는 실행 플랫폼이 지원하는 인증 기구를 자신의 설정으로 바꾸는 방법을 보여 줍니다.서버 TLS 관리자의 축복이 없습니다. 인증서 잠금을 사용하지 마십시오!
      private final OkHttpClient client;
    
      public CustomTrust() {
        client = new OkHttpClient();
        SSLContext sslContext = sslContextForTrustedCertificates(trustedCertificatesInputStream());
        client.setSslSocketFactory(sslContext.getSocketFactory());
      }
    
      public void run() throws Exception {
        Request request = new Request.Builder()
            .url("https://publicobject.com/helloworld.txt")
            .build();
    
        Response response = client.newCall(request).execute();
        System.out.println(response.body().string());
      }
    
      private InputStream trustedCertificatesInputStream() {
        ... // Full source omitted. See sample.
      }
    
      public SSLContext sslContextForTrustedCertificates(InputStream in) {
        ... // Full source omitted. See sample.
      }

    다음으로 전송:https://www.cnblogs.com/yuanchongjie/p/4971665.html

    좋은 웹페이지 즐겨찾기