안전한 SSL/TLS를 운영하기 위해 알아야 하는 것들

안녕하세요. LINE에서 Security Engineering을 담당하고 있는 이지훈입니다. 제가 속한 팀은 업무 환경과 서비스 환경에서 사용되는 인프라를 더욱 안전하게 만들어가는 업무를 담당합니다. 그 일환으로 SSL/TLS 인증서 관리나 관련 가이드를 제공하는 활동도 하고 있습니다. 대규모 환경에서는 보안은 물론 클라이언트와의 호환성이나 서비스 환경도 고려해야 하는데요. 오늘은 이와 관련된 경험 중 일부를 공유할까 합니다.

들어가며

우선 TLS(Transport Layer Security. 구(奮) SSL. 이하, 일반적인 표기에 따라 SSL/TLS로 표기)가 무엇인지 간단하게 살펴보는 것으로 시작하겠습니다. TLS는, 브라우저 같은 클라이언트가 공개된 인터넷 망을 통해 웹서버와 커뮤니케이션할 때, 여러 가지 보안 메커니즘을 제공하여 원하는 상대와 안전하게 연결될 수 있도록 도와주는 인터넷 프로토콜입니다. 현재 널리 이용되는 TLS 프로토콜의 기술적인 요건은 RFC 2246(TLS 1.0), RFC 4346(TLS 1.1), RFC 5246(TLS 1.2) 등 링크를 통해 확인하실 수 있는데요. 현재 지속적으로 보안 수준을 높여가고 있습니다. 최근(2018.3.21) Proposed Standard로 정해진 TLS 1.3의 경우 이미 알려진 보안 문제에 대한 대응이 설계에 추가로 반영되었습니다.

대표적으로 HTTP가 SSL/TLS를 이용하여 HTTPS(HTTP over TLS)를 제공하고 있으며, SNMP, FTP 등 다양한 인터넷 프로토콜에서도 SSL/TLS가 쓰이고 있습니다. 본 포스팅에서는 nginx와 같은 웹서버를 이용하여 웹서비스를 제공하는 경우를 가정하고 이에 대한 안전한 설정과 고려 사항에 대해 이야기하고자 합니다.

독자 여러분께서는 각자의 필요에 따라 다음과 같이 본 포스팅을 활용하실 수 있습니다.

  • 기술적인 이해 없이도 설명에 따라 안전한 설정을 하고 싶다. → 포스팅 앞 부분, 바로 이어지는 Step by Step 섹션을 읽어보시기 바랍니다.
  • 내용을 좀 더 이해하고 싶다. → 포스팅 뒷부분까지 전부 읽고, 인용되어 있는 외부 링크나 용어까지 추가로 확인해 볼 것을 권해드립니다.

Step by Step

편의상 Linux에서 nginx를 웹서버로 이용하는 경우를 예로 들어 설명하겠습니다. 다른 웹서버에 대해서는 각 설정 파일의 Directives에 대한 문서를 참조하시기 바랍니다.

Step #1. 인증서 발급 및 설정

우선 infraprotection.line.me 서비스에서 사용할 인증서를 미리 준비해둡니다. Comodo, DigiCert, GlobalSign 등과 같은 인증서 발급 기관이나 Let’s Encrypt 같이 무료로 발급해주는 곳에서 발급받습니다.

Let’s Encrypt에서 개별 인증서를 발급받으려면 다음과 같이 진행하면 됩니다.

Certbot Let’s Encrypt 클라이언트 설치

Certbot 패키지를 설치합니다.

$ sudo yum install certbot

인증서 발급

  1. 먼저 실습하려는 환경이 아래 전제조건을 만족하는지 확인합니다.
    • DNS의 A, 또는 CNAME records로 설정 가능
    • Port 80 외부 액세스 가능 확인
    • 본 예제에서는 port 80의 webroot 디렉터리를 /var/ssltest/로 설정
    • 도메인은 infraprotection.line.me로 가정
  2. 전제조건이 만족되면 certbot 클라이언트의 certonly 명령어 옵션으로 인증서를 발급 받습니다.
    $ sudo certbot certonly --webroot -w /var/ssltest/ -d infraprotection.line.me
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Enter email address (used for urgent renewal and security notices) (Enter 'c' to
    cancel): youremail (ex. lee.jihoon@linecorp.com)
    Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
    -------------------------------------------------------------------------------
    Please read the Terms of Service at
    https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
    in order to register with the ACME server at
    https://acme-v01.api.letsencrypt.org/directory
    -------------------------------------------------------------------------------
    (A)gree/(C)ancel:
    -------------------------------------------------------------------------------
    Would you be willing to share your email address with the Electronic Frontier
    Foundation, a founding partner of the Let's Encrypt project and the non-profit
    organization that develops Certbot? We'd like to send you email about EFF and
    our work to encrypt the web, protect its users and defend digital rights.
    -------------------------------------------------------------------------------
    (Y)es/(N)o:
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for infraprotection.line.me
    Using the webroot path /var/ssltest for all unmatched domains.
    Waiting for verification...
    Cleaning up challenges
    Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
    Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem
    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at
    /etc/letsencrypt/live/infraprotection.line.me/fullchain.pem. Your
    cert will expire on 2017-07-10. To obtain a new or tweaked version
    of this certificate in the future, simply run certbot again. To
    non-interactively renew *all* of your certificates, run "certbot
    renew"
    - If you like Certbot, please consider supporting our work by:
    Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
    Donating to EFF: https://eff.org/donate-le
    
  3. 발급이 완료되면 생성된 인증서 파일 정보를 확인합니다.
    • 생성 파일 확인 경로
      $ sudo ls -l /etc/letsencrypt/live/infraprotection.line.me/
      
    • 생성 파일 상세 내용
      • cert.pem: 서명된 인증서
      • chain.pem: Let’s Encrypt의 중간 인증서(intermediate certificate)
      • fullchain.pem: cert.pem 파일과 chain.pem 파일을 합친 파일
      • privkey.pem: 인증서의 개인키
  4. nginx 같은 웹서버에서는 다음과 같이 설정합니다.
    • Nginx 기본 설정
      $ sudo vim /etc/nginx/conf.d/ssl.conf
      
      server{
        .....
        ssl_certificate/etc/letsencrypt/live/infraprotection.line.me/fullchain.pem;
        ssl_certificate_key/etc/letsencrypt/live/infraprotection.line.me/privkey.pem;
        .....
      }
      
      • Nginx 1.3.7 이후 버전에서 OCSP stapling 기능을 사용하고 있는 경우
      $ sudo vim /etc/nginx/conf.d/ssl.conf
      
      server{
        .....
        ssl_stapling on;
        .....
        ssl_certificate/etc/letsencrypt/live/infraprotection.line.me/fullchain.pem;
        ssl_certificate_key/etc/letsencrypt/live/infraprotection.line.me/privkey.pem;
      
        ssl_trusted_certificate/etc/letsencrypt/live/infraprotection.line.me/chain.pem;
        .....
      }
      

자동 업데이트 설정

  1. ‘–dry-run’ 파라미터를 사용하여 자동 업데이트 설정 명령을 테스트합니다.
    $ sudo certbot renew --dry-run
    Saving debug log to/var/log/letsencrypt/letsencrypt.log
    
    -------------------------------------------------------------------------------
    Processing/etc/letsencrypt/renewal/infraprotection.line.me.conf
    -------------------------------------------------------------------------------
    Cert not due for renewal、but simulating renewal for dry run
    Starting new HTTPS connection(1):acme-staging.api.letsencrypt.org
    Renewing an existing certificate
    Performing the following challenges:
    http-01 challenge for infraprotection.line.me
    Waiting for verification...
    Cleaning up challenges
    Generating key(2048 bits):/etc/letsencrypt/keys/0001_key-certbot.pem
    Creating CSR:/etc/letsencrypt/csr/0001_csr-certbot.pem
    
    -------------------------------------------------------------------------------
    new certificate deployed without reload、fullchain is
    /etc/letsencrypt/live/infraprotection.line.me/fullchain.pem
    -------------------------------------------------------------------------------
    **DRY RUN:simulating'certbot renew'close to cert expiry
    **(The test certificates below have not been saved.)
    
    Congratulations、all renewals succeeded.The following certs have been renewed:
    /etc/letsencrypt/live/infraprotection.line.me/fullchain.pem (success)
    **DRY RUN:simulating'certbot renew'close to cert expiry
    **(The test certificates above have not been saved.)
    
    IMPORTANT NOTES:
    -Your account credentials have been saved in your Certbot
    configuration directory at/etc/letsencrypt.You should make a
    secure backup of this folder now.This configuration directory will
    also contain certificates and private keys obtained by Certbot so
    making regular backups of this folder is ideal.
    
  2. 문제 없이 작동되면 crontab에 등록합니다.
    $ sudo crontab -e
    05 8、20 * * * /usr/bin/certbot renew --renew-hook "systemctl reload nginx"
    
    $ sudo crontab -l
    05 8、20 * * * /usr/bin/certbot renew --renew-hook "systemctl reload nginx"
    

부록-인증서 관리

  • cerbot 클라이언트를 통해 관리하고 있는 인증서의 목록은 아래 명령어로 확인할 수 있습니다.
    $ sudo certbot certificates
    
  • 인증서가 만료되면 아래와 같이 인증서를 재발급받거나 갱신할 수 있습니다.
    $ sudo certbot revoke --cert-path /etc/letsencrypt/live/infraprotection.line.me/cert.pem
    Saving debug log to/var/log/letsencrypt/letsencrypt.log
    Starting new HTTPS connection(1):acme-v01.api.letsencrypt.org
    
    -------------------------------------------------------------------------------
    Congratulations!You have successfully revoked the certificate that was located
    at/etc/letsencrypt/live/infraprotection.line.me/cert.pem
    -------------------------------------------------------------------------------
    
    $ sudo certbot certonly --webroot -w /var/ssltest/ -d infraprotection.line.me
    Saving debug log to/var/log/letsencrypt/letsencrypt.log
    Starting new HTTPS connection(1):acme-v01.api.letsencrypt.org
    Cert not yet due for renewal
    
    You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
    (ref:/etc/letsencrypt/renewal/infraprotection.line.me.conf)
    
    What would you like to do?
    -------------------------------------------------------------------------------
    1:Keep the existing certificate for now
    2:Renew&replace the cert(limit~5 per 7 days)
    -------------------------------------------------------------------------------
    Select the appropriate number[1-2]then[enter](press'c'to cancel):2
    Renewing an existing certificate
    Performing the following challenges:
    http-01 challenge for infraprotection.line.me
    Using the webroot path/var/ssltest for all unmatched domains.
    Waiting for verification...
    Cleaning up challenges
    Generating key(2048 bits):/etc/letsencrypt/keys/0002_key-certbot.pem
    Creating CSR:/etc/letsencrypt/csr/0002_csr-certbot.pem
    
    IMPORTANT NOTES:
    -Congratulations!Your certificate and chain have been saved at
    /etc/letsencrypt/live/infraprotection.line.me/fullchain.pem. Your
    cert will expire on 2018-10-05.To obtain a new or tweaked version
    of this certificate in the future、simply run certbot again.To
    non-interactively renew*all*of your certificates、run"certbot
    renew"
    -If you like Certbot、please consider supporting our work by:
    
    Donating to ISRG/Let's Encrypt:https://letsencrypt.org/donate
    Donating to EFF:https://eff.org/donate-le
    
    $ sudo systemctl reload nginx
    

Step #2. 웹서버에서 TLS/SSL 설정

Step #2-1. OpenSSL 모듈 업데이트

우선 현재 시스템에서 사용하고 있는 OpenSSL 라이브러리를 업데이트합니다.

2018년 8월 현재 OpenSSL에서 배포하는 아래 버전을 기준으로 삼고, 각 시리즈 별로 그 이후 버전이나 운영체제가 배포하는 패키지의 최신 안정화 버전으로 업데이트해야 합니다.

  • 1.1.0i 혹은 그 이후 버전
  • 1.0.2p 혹은 그 이후 버전

Step #2-2. 설정 수정

프로토콜 및 cipher suite 설정

nginx 설정을 예로 들어 설명하겠습니다.

Category Directive
기본 설정 파일 nginx.conf
SSL 프로토콜 ssl_protocols TLSv1.1 TLSv1.2;
SSL CipherSuite ssl_ciphers “ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA”;
기타 설정 ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m;

안전한 키 길이를 가진 DHE 알고리즘 키 설정

‘/path/to/openssl’: 보통 ‘openssl’만 입력하면 됩니다. 다만 서버 하나에 여러 버전의 OpenSSL이 설치되어 있는 경우, 최근에 업데이트한 OpenSSL의 경로를 사용합니다.

$ sudo /usr/local/openssl/bin/openssl dhparam 2048

1. DH 파라미터 파일을 생성
$ sudo /path/to/openssl dhparam -out /etc/pki/tls/dhparams.pem 2048
$ sudo chmod 600 /etc/pki/tls/dhparams.pem

2. Config 파일에 생성된 DH 파라미터를 설정
$ sudo vim $SSL_CONFIGFILE (ex. /etc/nginx/nginx.conf)
ssl_dhparam /etc/pki/tls/dhparams.pem;

Step #2-3. 웹서버 재실행

웹서버 재실행 전에 수정된 설정 파일의 유효성 검사를 진행합니다. Graceful 옵션으로 재실행할 때는 새로 설치된 OpenSSL 라이브러리가 반영되지 않습니다. 따라서 ‘stop/restart’로 마스터 프로세스를 재실행해야 합니다.

Step #3. 결과 확인

설정이 제대로 되었는지 테스트해 보겠습니다. 공개된 서버라면 다음과 같이 Qualys SSL Labs Service를 이용하면 됩니다.

https://www.ssllabs.com/ssltest/analyze.html?d=[Test Domain]&hideResults=on
  • ‘hideResults=on’으로 설정하여 테스트 사이트 대시보드에 테스트 결과가 나타나지 않도록 주의하시기 바랍니다.

조금 더 알고자 하는 분들을 위해

Step by Step 섹션에서 문제 없이 설정을 마쳤다면, 위 Step #3에서 ‘A’ 수준의 테스트 결과가 나올 것입니다.
그 내용을 더 잘 이해하고, 더 안전하게 설정하고자 한다면 아래 내용을 추가로 확인해 주세요.

안전(secure)한 상태란?

일정한 기준을 충족시키지 못한 보안 메커니즘(Security Mechanisms)은 공격자에게 악용당할 우려가 있는 취약한 상태가 됩니다. 설정에 신경 쓰지 않으면 안전하지 않은 상태가 되어 버릴 수 있다는 뜻입니다. 따라서, 보안 매커니즘이 필요한 기준을 충족시킨 상태를 안전한 상태라고 할 수 있습니다.

SSL/TLS 구현에서 ‘안전(secure)한’ 상태란 다음 기준을 만족하는 상태라고 할 수 있습니다.

  • Criteria #1. 클라이언트가 신뢰할 수 있는 상태의 인증서여야 합니다.
  • Criteria #2. 안전한 설정이 되어 있어야 합니다.
    • Criteria #2-1. 안전한 프로토콜을 제공하고(Protocol support) 있어야 하며,
    • Criteria #2-2. 안전한 암호(Secure Cipher Suites) 설정이 되어 있어야 합니다.

Step by Step 섹션에서도 위 두 부분으로 나누어 설명을 드렸었는데요. 좀 더 세부적으로 살펴보겠습니다.

Criteria #1. 클라이언트가 신뢰할 수 있는 인증서

클라이언트가 신뢰할 수 있는 인증서는 일반적으로는 다음과 같은 방법으로 획득하고 설정합니다.

  1. 서비스 도메인에 적합한 인증서 유형을 확인합니다.
  2. GlobalSign, DigiCert 등 신뢰할 수 있는 Root CA(certificate authority)에서 인증서를 구매하여 만료되지 않도록 관리하거나, Let’s Encrypt, AWS Certificate Manager처럼 무료로 이용할 수 있는 CA를 통해 자동 갱신되도록 인증서를 발급받습니다.
  3. 발급받은 인증서의 개인키(private key)를 안전하게 저장합니다.
  4. 웹서버에서 적절한 중간 CA 인증서를 설정하여 클라이언트에서 Chain of Trust를 확인할 수 있도록 합니다.

적절한 인증서 유형이란?

일반적으로 사용하는 서버 인증서에는 여러 종류가 있습니다. FQDN(fully qualified domain name, 정규화된 도메인 이름)에 대한 신뢰를 제공하기 위해 개별 인증서를 발급받는 경우 외에도, 여러 FQDN에 대한 신뢰를 한번에 제공하기 위한 SAN(Subject Alternative Name) 인증서, 와일드카드 문자 “*”를 접두사로 사용하여 서브도메인 전체에 대한 신뢰를 제공하는 Wildcard 인증서 등의 유형이 있습니다.

우선 본격적인 설명에 들어가기 앞서 도메인 이름(Domain name)에 대해 이해할 필요가 있습니다. FQDN이란 Subdomain부터 TLD(.me와 같은 Top-Level Domain)까지를 포함하는 완전한 도메인 이름을 말하며, 아래와 같은 형식으로 되어 있습니다.

[subdomain levelN].[subdomain level2]…[subdomain level1].[apex domain].[tld(top–level domain)]

(도메인 이름에 대해 더 알고 싶으신 분은 RFC 1035의 내용을 참고하시기 바랍니다.)

그런데 위에 언급한 유형 중 Wildcard 인증서를 이용하다 보면 도메인 커버리지에 대해 잘못 알고 실수하기 쉽습니다. 모든 경우에 Wildcard 인증서를 사용할 수 있는 줄로 잘못 알고 설정해버릴 수 있는데요. Wildcard 인증서는 ‘첫 번째 레벨의 Subdomain에 대해서만 유효한 도메인’에 대해 커버리지가 존재합니다. 예를 들어, *.line.me Wildcard 인증서는 infraprotection.line.me와 같이 첫 번째 레벨의 서브도메인을 가진 도메인에는 이용 가능합니다. 하지만 tls.infraprotection.line.me처럼 두 번째 레벨의 서브도메인을 가진 서비스에 설정하면 클라이언트는 이를 신뢰하지 않게 됩니다. 따라서 이런 경우에도 같은 인증서를 이용하고 싶다면, tls-infraprotection.line.me와 같은 형태로 서비스의 도메인을 바꿔주어야 합니다.

신뢰할 수 있는 CA에서 인증서 획득하기

브라우저의 설정 화면에서 기본적으로 신뢰하고 있는 인증서의 정보를 확인할 수 있는데요. 아래 Chrome 브라우저의 Trusted Root CA 목록처럼 다양한 인증서가 있습니다.

어느 CA를 선택해야 할지에 대해서 CA/Browser Forum에선 다음과 같이 말하고 있습니다.

How to select your CA?
It is crucial to choose the most suitable Certification Authority for the sake of your certificate. You should take care of the reputation of the CA together with its convenience and certificate prices while choosing the best one for you.

위의 내용에 더해 조금 더 고려해야 할 사항을 적어보겠습니다.

  • CA의 평판

    • CA별 점유율에 대해서는 W3Techs의 Survey에서 확인할 수 있습니다.이 글을 작성하고 있는 2018년 현재, Let’s Encrypt의 Cross Root(여기에 대해서는 아래의 Trust Path 항목을 참고)인 IdenTrust가 가장 높은 점유율을 기록하고 있습니다.
  • Certificate Transparency 참여 여부

    • SSL/TLS 인증서를 사용할 때 가장 중요한 전제 조건은 CA를 신뢰할 수 있어야 한다는 것입니다. CA가 실수로 인증서를 발급하거나, 혹은 CA가 훼손(Compromise)된 상황에서 잘못된 인증서가 발급될 수도 있는데요. 이에 대비하여 Chrome 같은 브라우저에서는 발급 기록을 투명성 로그에 남길 경우에만 신뢰하고 있습니다. 따라서 Google의 Certificate Transparency에 참여하고 있는지, 그리고 향후 SCT(signed certificate timestamp) 대응 계획이 있는지 확인이 필요합니다.
    • 참여하고 있는 CA에서 인증서 발급 시 로그를 기록해서, 특정 도메인에 대한 인증서 발급 현황에 대해 인증서 검색 서비스 등에서 누구나 조회할 수 있습니다. 예를 들어 Let’s Encrypt는 CT에 참여하고 있기 때문에, 발급된 인증서에 대해서 이렇게 확인할 수 있습니다.
  • CA/Browser Forum의 Base Requirement에 따른 운영 여부

    • CA/Browser Forum의 Base Requirement 정책에 입각한 구현 계획이 있는지 확인해야 합니다.
    • 혹시라도 여기에서 정하고 있는 요구사항을 정해진 기한 내에 구현하지 못했을 경우, 정상적으로 발급된 인증서라도 웹브라우저에서 신뢰할 수 없는 상태가 될 수 있기 때문입니다.

무료 인증서 발급을 지원하는 Let’s Encrypt 역시 신뢰할 수 있는 CA입니다. 또한, 인증서에는 유효 기간이 있으니 만료일이 되기 이전에 재발급받아 항상 신뢰할 수 있는 상태로 유지해야 합니다.

개인키 안전하게 관리하기

앞서 예로 든 Let’s Encrypt에서 정상적으로 인증서를 발급받았다면 해당 디렉토리에 여러 개의 파일이 생성됩니다. 생성된 각 파일의 목적은 아래와 같습니다. 물론 다른 CA를 통해 발급받는 경우에도 같은 목적의 인증서 내용을 얻을 수 있습니다.

(목록에는 빠져 있지만, 인증서를 발급할 때 CA에 서명을 요청하기 위한 CSR(Certificate Signing Request) 파일을 생성하게 됩니다. 발급 프로세스 이후엔 사용되지 않기 때문에 목록에 추가하지 않았습니다.)

Index Purpose Filename
1 CA로부터 서명 받은 인증서(X.509 형식) cert.pem
2 인증서의 개인키(Certificate’s private key) privkey.pem
3 중간 CA의 인증서 chain.pem
4 Fullchain(1+3 combined) fullchain.pem

위 인증서 파일 중 2번, ‘인증서의 개인키’는 패스워드처럼 안전하게 관리해야 합니다. 따라서 ‘인증서의 개인키’는 실제 사용해야 하는 서버 등 안전한 곳에서 최초 생성된 후에 다른 곳에 공개하지 않도록 주의해야 합니다. 서버 내에서도 root 등 관리자를 소유자로 하고, 다른 사용자는 접근할 수 없도록 설정합니다. 다른 파일의 내용은 클라이언트가 접속할 때 전달되므로 공개되어도 괜찮습니다.

인증서 경로(Trust Path)와 중간(Intermediate) CA의 인증서

위 인증서 파일 중 3번과 4번에 해당하는 이야기입니다.

인증서를 획득해서 시스템에 안전하게 보관해 두었다면, 이번에는 클라이언트가 해당 인증서를 신뢰할 수 있도록 충분한 정보를 전달하게 만들 차례입니다. 신뢰할 수 있는 경로(Chain of Trust)를 지정해주는 것인데요. 보통 중간 CA 정보를 추가로 설정하면 되지만, 특수한 경우(피처폰처럼 오래된 단말기를 지원해야 하는 경우)에 대비해 일부 CA에서 제공하는 Cross Signed Root를 설정해야 할 때도 있습니다.

신뢰할 수 있는 경로(Chain of Trust)와 중간 CA

클라이언트는 접속할 서버에서 보내온 인증서의 내용을 확인하고, 신뢰할 수 있는 CA가 서명한 것인지 확인하게 됩니다. 참고로, openssl을 이용하여 확인하고 싶은 경우에는 아래와 같은 명령어로 할 수 있습니다.

$ openssl s_client -connect global-root-ca.chain-demos.digicert.com:443 -showcerts -servername global-root-ca.chain-demos.digicert.com
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Utah, serialNumber = 5299537-0142, C = US, ST = Utah, L = Lehi, O = "DigiCert, Inc.", CN = global-root-ca.chain-demos.digicert.com
verify return:1
---
Certificate chain
 0 s:/businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Utah/serialNumber=5299537-0142/C=US/ST=Utah/L=Lehi/O=DigiCert, Inc./CN=global-root-ca.chain-demos.digicert.com
   i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
-----BEGIN CERTIFICATE-----
MIIFnzCCBIegAwIBAgIQDZzoezayHYgZcb6176w9szANBgkqhkiG9w0BAQsFADBN

'이하 생략'

아래는 Digicert의 데모 사이트에 설정되어 있는 인증서의 발급 경로입니다. 서버에 설정된 Leaf 인증서인 global-root-ca.chain-demos.digicert.com을 중간 CA인 DigiCert SHA2 Secure Server CA가 서명했고, 해당 중간 CA는 DigiCert Root CA가 서명했습니다.

클라이언트는 위 DigiCert처럼 이미 신뢰하고 있는 Root CA에 대한 정보를 ‘신뢰하고 있는 Root CA의 목록’으로 설정한 상태이며, 전달받은 Leaf 인증서를 서명한 중간 CA 정보, 그리고 중간 CA를 서명한 Root CA에 대한 정보를 차례대로 확인(Chain of Trust)하여 검증하게 됩니다.

Leaf Certificate (Verify) -> Intermediate CA (Verify) -> Root CA

Wikipedia를 보시면 그림과 함께 설명되어 있습니다. 따라서 만약 중간 CA에 대한 정보를 클라이언트에 전달하지 않을 경우, Root CA에 대한 신뢰 관계를 검증하지 못하게 될 수 있습니다. 실제로는 대부분의 클라이언트가 ‘신뢰하고 있는 Root CA의 목록’ 뿐 아니라 ‘신뢰하고 있는 중간 CA’에 대한 정보도 설정하고 있습니다. 그렇기 때문에 중간 CA 설정을 하지 않아도 문제없는 경우가 많지만, 일부 클라이언트에는 정보가 없을 수도 있기 때문에 설정해 두는 편이 안전합니다. 그런데 읽다 보면 이런 생각이 들 수도 있습니다.

‘Root CA가 Leaf 인증서를 직접 서명(발급)하도록 하면 간단할텐데 왜 중간 CA를 두는 것일까?’

Root CA는 이름 그대로 인증서 신뢰 관계의 원점(Trust anchor)이기 때문에 Root CA가 훼손될 경우 신뢰 구조 전체가 무너지게 됩니다. 따라서 네트워크에서 분리된(Air Gapped 또는 오프라인) 환경에서 안전하게 관리되어야 합니다(이런 부분이 잘 관리되고 있는지 검증받아야 CA가 될 수 있기도 합니다). 이렇게 Root CA는 중간 CA를 발급(서명)하는 경우에만 제한적으로 사용되고, Root CA를 이용해 발급한 중간 CA만 시스템 상에 온라인으로 두고 Leaf 인증서 발급(서명)에 사용하는 위와 같은 구조가 되는 것입니다.

Cross Root, 혹은 Cross Signed Root

Cross Signed Root라 불리는 인증서를 설정해야 할 때도 있습니다. 이것은 무엇일까요?

우선 클라이언트 쪽에서 생각해 보겠습니다. 위에서 클라이언트가 ‘신뢰하고 있는 Root CA의 목록’을 갖고 있다고 했는데요. 해당 목록이 오래 전에 작성되고 이후 업데이트되지 않은 경우를 생각해 볼 수 있습니다. 이를 테면, 구형 휴대 전화나 매우 오래된 OS(예를 들면, CentOS 4 또는 초기 CentOS 5 등)와 같은, 매우 오래된 클라이언트 환경에선 해당 Root CA를 ‘신뢰하고 있는 Root CA의 목록’에 포함하고 있지 않을 수도 있습니다. 혹은 Root CA가 작성된 지 얼마 안된 경우도 생각해 볼 수 있습니다. 그렇다면 해당 Root CA를 웹브라우저와 같은 클라이언트에서 기본적으로 포함하고 있지 않은 상황이 됩니다.

이런 경우에 대비해 호환성이 높은, 즉, 오래 전에 발급되어 대부분의 클라이언트가 ‘신뢰하고 있는 Root CA의 목록’에 포함하고 있는 Root CA를 통하여 서명을 받아두기도 합니다. 실제 사례를 보면 좀 더 이해가 쉬울 텐데요. 다음은 Baltimore CyberTrust Root를 통해 서명한 DigiCert인증서 사례입니다.

다른 예로는 Let’s Encrypt가 자신들의 Root CA인 ISRG Root X1 외에도 IdenTrust의 DST Root CA X3을 통해 Cross Signing한 것 등을 들 수 있습니다(참고).

SNI(Server Name Indication)

인증서는 정상이지만, 실제 웹브라우저 같은 클라이언트로 다른 인증서가 전달된 사례도 알아 두시는 편이 좋습니다. IP Address, Port가 동일한 하나의 웹서버라도, 서버 블록을 여러 개 설정하여 여러 도메인에 서비스할 수 있습니다. 이 경우 SNI가 지원되는 클라이언트라면 접속하고자 하는 호스트네임을 요청하여 적절한 인증서를 받아올 수가 있지만, SNI를 지원하지 않는 클라이언트의 경우 웹서버에 설정된 첫 번째 서버 블록의 인증서를 받아오지 않으면 신뢰할 수 없다고 판단해버릴 수 있습니다.

만약, 서버 블록 두 개만 서비스하는데 둘 중 하나의 서비스만 SNI를 지원하지 않는 클라이언트를 고려해야 한다면, 그 서비스를 서버 블록 앞 쪽으로 이동시켜 해결할 수 있습니다. 다만 이런 경우에 보다 일반적인 해결 방법은, 서비스하는 모든 도메인을 포함한 SAN 인증서를 이용하는 것입니다. 그렇게 하면 SNI를 지원하지 않는 클라이언트도 요청한 호스트명에 해당하는 인증서를 받아올 수 있게 됩니다.

Criteria #2. 안전한 설정(Secure Configuration)

아래 순서에 따라 안전한 설정이 되었는지 확인할 수 있습니다.

  1. 사용하는 OpenSSL 라이브러리를 최신 버전으로 업데이트한다.
  2. 안전하지 않은 프로토콜은 서비스하지 않도록 설정한다.
  3. 안전한(보안 강도가 충분한) cipher suite가 설정되도록 한다.
  4. 위 기본 설정보다 더 안전한 연결을 제공하고 싶다면 추가적인 보안 설정을 한다.

참조 설정

다음은 nginx의 nginx.conf 파일입니다. 이번 포스팅에서 설명하지 않은 부분에 대해서는 nginx 공식 문서에서 ngx_http_ssl_module 관련 Directive 부분을 읽어보시면 됩니다.

http {
    server {
        listen       80;
        server_name  infraprotection.line.me;

        # redirect http > https
        return 301 https://$host$request_uri;

        location / {
            root   /var/infraprotection/;
            index  index.html index.htm;
        }

        # For DV(Domain Validation) when using Let's Encrypt
        location ^~ /.well-known/acme-challenge/ {
                default_type "text/plain";
                root   /var/infraprotection/;
        }


        error_page 400 401 403 404 500 501 502 503 505 https://infraprotection.line.me/;
    }

    server {
        listen       443 ssl http2;
        server_name  infraprotection.line.me;

        keepalive_requests 10;
        keepalive_timeout 20;

        # Set Headers such as HSTS
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;

        # if the service use Normal Intermediate CA(中間CA)
        ssl_certificate      /etc/pki/tls/certs/infraprotection.line.me_fullchain.crt;
        # else if the service use Cross Root CA
        # ssl_certificate    /etc/pki/tls/certs/infraprotection.line.me_fullchain_cross.crt;

        # Certificate private key Path
        ssl_certificate_key  /etc/pki/tls/private/infraprotection.line.me.key;

        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;

        server_tokens off;

        # Set cipher suite
        ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA";
        ssl_prefer_server_ciphers  on;
        # Only Allow TLSv1.2
        ssl_protocols TLSv1.2;


        # Set strong parameter for DH key exchange
        ssl_dhparam /etc/pki/tls/dhparams4096.pem;


        #
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/pki/tls/certs/infraprotection.line.me_chain.crt;

        error_page 400 401 403 404 500 501 502 503 505 https://infraprotection.line.me/;

        location / {
            root   /var/infraprotection.line.me/;
            index  index.html index.htm;
        }
    }
}

최신 OpenSSL 라이브러리

로드밸런서(Load Balancer) 등을 이용해서 TLS Termination하는 경우가 아니라면, 보통 시스템에 설치된 OpenSSL 라이브러리를 사용해서 SSL/TLS를 제공하게 되는데요. 이와 관련해 고려해야 할 사항에 대해 적어보겠습니다.

라이브러리의 커플링(Coupling)

nginx 등의 웹서버를 설치할 때 OpenSSL 라이브러리를 함께 빌드(Static Build)하도록 가이드하는 경우를 많이 보았습니다. 하지만 이렇게 하면 커플링(Coupling)이 불필요하게 높아져서 OpenSSL의 취약점 대응 등 업데이트가 필요할 때 웹서버를 새로 빌드해서 배포해야 하는 문제가 생깁니다. 따라서 OpenSSL 라이브러리 업데이트 등의 향후 관리 업무를 고려한다면 시스템 라이브러리를 사용할 것을 권장하며(예: $sudo yum update openssl), 정적 빌드(static build)버전은 사용하지 않는 것이 좋습니다.

정적으로 연결된 OpenSSL 인스턴스를 사용하도록 설정했는지에 대한 설정 파라미터 값은 아래와 같이 확인할 수 있습니다.

$ nginx -V(예:/usr/sbin/nginx -V)

또는 빌드된 바이너리를 직접 체크하여 확인할 수도 있습니다.

$ strings -a /usr/local/nginx-installed-path/sbin/nginx | grep '^OpenSSL[0-9]' | awk '{print$2}' | head -n 1

정적으로 연결된 라이브러리 대신 시스템에 설치된 OpenSSL 패키지를 사용하려면, nginx 웹서버에선 다음과 같이 하면 됩니다.

$ sudo yum install openssl-devel
$ sudo yum update openssl

nginx 빌드 시에 “–with-openssl parameter”를 삭제합니다.

OpenSSL 버전

아래 명령어를 통해 설치된 라이브러리 버전 정보를 확인할 수 있습니다.

$ /path/to/openssl version -a
$ yum list installed openssl

RHEL(Red Hat Enterprise Linux) 등에서 배포하는 OpenSSL 라이브러리 버전을 확인해 보면 조금 이상하다는 생각이 들 것입니다. RHEL 6에서 배포하는 OpenSSL x86_64 아키텍처의 경우 패키지 명이 ‘openssl-1.0.1e-57.el6.x86_64’와 같은 형태인데요. 이유는 Upstream인 OpenSSL의 버전과는 버전 명명 규칙이 다르기 때문입니다. 이런 경우엔 각 운영체제 벤더가 운영하는 저장소에 배포되는 최신 버전의 라이브러리로 업데이트($ sudo yum update openssl)하면 됩니다.

기타 참고 사항

OpenSSL 0.9.8 및 1.0.0 버전은 TLSv1.1 이상의 프로토콜을 지원하지 않습니다(참고). 따라서 OpenSSL을 1.0.2/1.1.0 시리즈의 버전으로 업데이트해야 합니다(참고).

  • OS가 OpenSSL 1.0.2 이후 버전을 공식 지원하지 않는 경우(예를 들어 RHEL 5), OS를 상위 버전으로 업그레이드하기 전까지는 정적 빌드 버전을 사용할 필요가 있습니다.
  • OpenSSL 1.0.1 시리즈는 2016년 12월 31일에 공식 지원이 종료되어 보안 업데이트가 제공되지 않습니다. 1.0.2 등 상위 버전을 사용해야 합니다.
  • OpenSSL 1.1.1 시리즈는 안정화 전까지는 테스트 목적으로만 사용하는 것이 좋습니다.

Protocol

글 앞 부분에서도 언급한 바와 같이 최근(2018.3.21) Proposed Standard로 정해진 TLS 1.3설계에 이미 알려진 보안 문제에 대한 대응이 추가로 반영되는 등 TLS 프로토콜은 지속적으로 보안 수준을 높여가고 있는데요. PCI-DSS (PCI Security Standards Council)에서는 낮은 버전의 프로토콜을 상위 버전의 프로토콜로 마이그레이션하도록 규제하고 있기도 합니다(Migrating from SSL and Early TLS v1.1).

보안성을 위해서는 상위 버전의 프로토콜만 사용하도록 설정해야 합니다. 단, 상위 프로토콜을 지원하지 않는 클라이언트가 있을 수 있으니 호환성을 확인하고 마이그레이션해야 합니다. 예를 들어 하위 버전의 프로토콜에 대한 지원을 제한하면, 일반적인 사용자 환경 외에도, 연계되어 있는 타사 시스템 등의 클라이언트가 연결에 실패할 수도 있습니다. 따라서 연결을 테스트해 볼 수 있는 환경(Handshake Simulation)을 준비하여 클라이언트 쪽에 마이그레이션 계획 및 일정을 알린 후에 마이그레이션을 진행하는 방식으로 접근해야 합니다.

Android 2.3.7, 4.0.4, 4.1.1, 4.2.2, 4.3
IE 10 / Win Phone 8.0
Baidu Jan 2015
IE 7/Vista, 8-10/Win 7
Java 7u25
OpenSSL 0.9.8y
Safari 5.1.9 / OS X 10.6.8, 6.0.4 / OS X 10.8.4

안전한 cipher suite

Cipher suite는 안전한 연결을 생성하는 데 필요한 4개의 암호화 알고리즘을 하나로 모아(suite) 표현한 것입니다.

4개의 암호화 알고리즘이란 ‘키 교환 알고리즘(Key exchange/agreement)’, ‘접속 시 상대를 확인하기 위한 인증 알고리즘(Authentication)’, ‘기밀성을 위한 블록 암호화 알고리즘(Block/stream cipher)’, ‘메시지 무결성을 위한 암호화 알고리즘(Message authentication)’입니다. 위의 예에서 설정한 cipher suite, 암호 알고리즘은 아래와 같은 openssl 명령어로 확인할 수 있습니다.

$ openssl ciphers -v 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA' | column -t
ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=RSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=RSA  Enc=AESGCM(128)  Mac=AEAD
DHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=DH    Au=RSA  Enc=AESGCM(256)  Mac=AEAD
DHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=DH    Au=RSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=RSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=RSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES256-SHA         SSLv3    Kx=ECDH  Au=RSA  Enc=AES(256)     Mac=SHA1
ECDHE-RSA-AES128-SHA         SSLv3    Kx=ECDH  Au=RSA  Enc=AES(128)     Mac=SHA1
DHE-RSA-AES256-SHA256        TLSv1.2  Kx=DH    Au=RSA  Enc=AES(256)     Mac=SHA256
DHE-RSA-AES128-SHA256        TLSv1.2  Kx=DH    Au=RSA  Enc=AES(128)     Mac=SHA256
DHE-RSA-AES256-SHA           SSLv3    Kx=DH    Au=RSA  Enc=AES(256)     Mac=SHA1
DHE-RSA-AES128-SHA           SSLv3    Kx=DH    Au=RSA  Enc=AES(128)     Mac=SHA1
AES256-GCM-SHA384            TLSv1.2  Kx=RSA   Au=RSA  Enc=AESGCM(256)  Mac=AEAD
AES128-GCM-SHA256            TLSv1.2  Kx=RSA   Au=RSA  Enc=AESGCM(128)  Mac=AEAD
AES256-SHA256                TLSv1.2  Kx=RSA   Au=RSA  Enc=AES(256)     Mac=SHA256
AES128-SHA256                TLSv1.2  Kx=RSA   Au=RSA  Enc=AES(128)     Mac=SHA256
AES256-SHA                   SSLv3    Kx=RSA   Au=RSA  Enc=AES(256)     Mac=SHA1
AES128-SHA                   SSLv3    Kx=RSA   Au=RSA  Enc=AES(128)     Mac=SHA1

Cipher suite는 RFC에서 정의하는 이름을 사용하기도 하고(Naming scheme), OpenSSL에서 정의하는 이름을 사용하기도 해서 헷갈릴 수 있습니다. 이를 위한 맵핑 표를 제공하는 곳이 있으니 참고하시기 바랍니다.

각각의 알고리즘에 대해 이번에 설명하지는 않습니다만, 실제 해당 알고리즘이 어디에 사용되는지 생각해보는 것은 좀 더 깊게 이해하는 데에 도움이 될 수 있습니다. 예를 들어 키 교환에 DH를 사용했을 때 인증을 위한 RSA가, DH 알고리즘에서 키를 각각 도출하기 위해 공유한 파라미터에 서명하는 방식으로 사용되도록 구현된 부분에 대해서 생각해 보는 것이죠.

또한 대규모 트래픽을 처리하는 장비에서는 cipher suite별 성능에 대해 고민해야 하는 경우도 있습니다. 얼핏 생각하면 ECDHE를 사용하여 키 교환을 할 때 가장 빠르게 처리될 것 같지만, 실제로는 키 교환 외에도 인증을 위해 RSA를 추가로 사용해야 하기 때문에 키 교환과 인증 모두에 RSA를 사용할 때보다 처리 성능이 떨어지기도 합니다. 하드웨어적인 제약으로, DHE를 사용할 때보다 ECDHE를 사용했을 때 성능이 더 떨어지기도 합니다. 따라서 처리 성능이 중요한 경우라면 실제 테스트를 해보는 편이 좋습니다.

OpenSSL 라이브러리에선 !aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 같은 특별한 표현을 사용하기도 하는데요. 자주 쓰이는 내용은 아래와 같습니다.

!:제외함
aNULL:인증 기능이 없는 cipher suite. 따라서 Man-In-The-Middle (MITM) 공격에 취약함
eNULL(NULL):암호화하지 않는 cipher suite(null-encryption ciphers).
EXPORT:미국의 관련 법에 따라 수출이 가능한 40, 56 Bits의 약한 cipher suite.
DES:DES를 사용하는 cipher suite.
MD5:MD5를 사용하는 cipher suite.
PSK:PSK(pre-shared keys)를 사용하는 cipher suite.
RC4:RC4를 사용하는 cipher suite.
HIGH:"High" 수준의 cipher suites의 목록입니다. OpenSSL 버전마다 포함되는 cipher suite가 다르며, 현재는 128 bit 보다 큰 키 길이를 가지는 cipher를 사용하는 cipher suite입니다.
MEDIUM:"Medium" 수준의 cipher suites의 목록입니다. OpenSSL 버전마다 포함되는 cipher suite가 다르며, 현재는 128 bit 암호를 사용하는 cipher suite입니다.
LOW:"Low" 수준의 cipher suites의 목록입니다. OpenSSL 버전마다 포함되는 cipher suite가 다르며, 현재는 64/56 bit 암호를 사용하는 cipher suite입니다. 하지만 Export 수준의 cipher suite들은 제외합니다.
@STRENGTH:암호화 알고리즘(Encryption Algorithm) 키 길이의 순서로 현재 cipher 목록을 정렬하기 위해 사용할 수 있습니다.

더욱 자세한 내용은 이곳에서 확인하실 수 있습니다.

Criteria #3. 등급(Rating) Guide

위에서 설정이 제대로 되었는지를 Qualys SSL Labs Service에서 제공하는 서비스로 확인하는 방법을 설명드렸는데요. 이 부분이 더 궁금하신 분을 위해 설명을 보충해 보겠습니다.

Qualys SSL Labs Service에서는 아래와 같은 스코어링 방법(Scoring Scheme)으로 가중치 등을 정의하는 것으로 알려져 있습니다. 하지만 항목이 변경되는 등의 이유로 Grade T가 부여되는 경우 등이 모든 경우가 포함되어 있지는 않으니, 더 세부적인 내용은 관련 페이지를 참고하시기 바랍니다.

Category Scoring Weight Score Criteria Rating Guide
a certificate to verify that it is valid and trusted. N/A

CertificateInspection= {0, 1}

Set Zero Score, if

  • Domain name mismatch

  • Certificate not yet valid

  • Certificate expired

  • Use of a self-signed certificate

  • Use of a certificate that is not trusted (unknown CA or some other validation error)

  • Use of a revoked certificate

  • Insecure certificate signature (MD2 or MD5)

  • Insecure key

server configuration / Protocol support ProtocolSupportWeight = 30%

ProtocolSupport

= (Score of the best protocol + Score of the worst protocol) / 2

Protocol support rating guide

  • SSL 2.0 = 0%
  • SSL 3.0 = 80%
  • TLS 1.0 = 90%
  • TLS 1.1 = 95%
  • TLS 1.2 = 100%
server configuration / cipher suites

KeyExchangeWeight = 30%

KeyExchange

= Key exchange rating

Key exchange rating guide

  • Weak key (Debian OpenSSL flaw) = 0%
  • Anonymous key exchange (no authentication) = 0%
  • Key or DH parameter strength < 512 bits = 20%
  • Exportable key exchange (limited to 512 bits) = 40%
  • Key or DH parameter strength < 1024 bits (e.g., 512) = 40%
  • Key or DH parameter strength < 2048 bits (e.g., 1024) = 80%
  • Key or DH parameter strength < 4096 bits (e.g., 2048) = 90%
  • Key or DH parameter strength >= 4096 bits (e.g., 4096) = 100%
CipherStrengthWeight = 40%

CipherStrength

= (Score of the strongest cipher + Score of the weakest cipher) / 2

Cipher strength rating guide

  • 0 bits (no encryption) = 0%
  • < 128 bits (e.g., 40, 56) = 20%
  • < 256 bits (e.g., 128, 168) = 80%
  • >= 256 bits (e.g., 256) = 100%

위에서 산출된 점수를 아래와 같이 Grade로 변환하여 보여줍니다.

Numerical Score Grade
score >= 80 A
score >= 65 B
score >= 50 C
score >= 35 D
score >= 20 E
score < 20 F

글을 맺으며

이상으로 안전한 SSL/TLS를 실현하는 방법에 관한 포스팅을 마칩니다. 이번 포스팅를 위해 많은 동료들이 해당 내용을 서버에 직접 적용해 주었습니다. 각종 유용한 분석 정보와 전문 지식을 제공해 준 동료들에게 고맙다는 인사를 전합니다.

Related Post