SSL/TLS

HPKP (HTTP Public Key Pinning) 개념과 설정

  • jroh

1. HPKP (HTTP Public Key Pinning) 이란?

SSL/TLS로 이루어진 암호화 통신은 중간자 공격(Man in the Middle)에 취약합니다. 공격자 또는 보안장비가 암/복호화에 사용할 인증서를 임의로 교체하여 중간에서 데이터를 복호화 하는 것이죠.

클라이언트(유저)가 SSL/TLS 암호화 통신에 사용할 인증서를 최종서버의 인증서로 고정(Pinning)하는 것을 HPKP(HTTP Public Key Pinning)이라고 합니다.

2. HPKP 핀 확인 및 생성 방법

인증서의 PIN을 확인하는 방법:

  • OpenSSL 명령:
root@rsec:/rsec.kr# openssl x509 -pubkey < fullchain.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
O2ELvEUIPxmsA7vJAbZxoiABBkonE3U+INXiuRkWTu4=

인증서가 갱신되면 PIN도 바뀌므로 Backup Pin을 생성하여 사용합니다:

root@rsec:/rsec# openssl genrsa -out rsec.kr.backup.key 4096
root@rsec:/rsec# openssl req -new -key rsec.kr.backup.key -sha256 -out rsec.kr.backup.csr
root@rsec:/rsec.kr# openssl req -pubkey < rsec.kr.backup.csr | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
T3QGJPkeB/a0wqVRQLP1AMsOTOxc8OJOR6nczDNd7H4=

3. HPKP 적용하기

Public-Key-Pins: pin-sha256="base64=="; max-age=expireTime [; includeSubDomains][; report-uri="reportURI"]
  • pin-sha256: Base64 형식 PIN (SPKI)
  • max-age: 브라우저에 PIN을 유지할 시간 (초)
  • includeSubDomains: SubDomain까지 HPKP 확장
  • report-uri: pin validation 실패시 report URI

NGINX:

add_header Public-Key-Pins 'max-age=31536000;
    pin-sha256="O2ELvEUIPxmsA7vJAbZxoiABBkonE3U+INXiuRkWTu4=";
    pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=";
    pin-sha256="Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys=";
    pin-sha256="T3QGJPkeB/a0wqVRQLP1AMsOTOxc8OJOR6nczDNd7H4=";
    includeSubDomains';

4. 기타

HPKP의 효용성은 DigiNotar 사건에서 알려졌습니다. 다른 브라우저는 잘못된 구글 인증서를 검출하지 못했지만 구글 크롬은 Certificate Pinning으로 미리 경고해 주었습니다. 관련 사례는 DNS CAA레코드는 무엇일까? 2번 항목을 참고.


📎

HSTS (HTTP Strict Transport Security) 개념과 설정SSL/TLS