OCSP 응답·요청 디코더
DER 파일, base64, PEM, 패킷 캡처의 16진수 문자열 중 무엇으로 주든 RFC 6960 메시지를 읽어 클라이언트가 보는 그대로 펼쳐 놓습니다. 응답이라면 먼저 OCSPResponseStatus를 봅니다. 데이터를 담는 것은 successful 뿐이라, 6바이트짜리 tryLater도 그 자체로 완결된 정상 응답이며 어떤 인증서에 대해서도 아무 말을 하지 않습니다. 이걸 잘린 파일로 오해하는 일이 흔합니다. 이어서 응답기 ID와 그 형태(이름인지 응답기 키의 SHA-1 해시인지), producedAt, 그리고 단일 응답마다 CertID, good·revoked·unknown 상태, thisUpdate, nextUpdate, 폐기된 경우 폐기 시각과 CRLReason을 표시합니다. 논스, 아카이브 컷오프, CRL 참조, extended-revoke처럼 읽을 가치가 있는 확장은 OID로 나열하지 않고 실제 값으로 풀어 줍니다. extended-revoke가 설정된 응답기는 발급한 적 없는 인증서에도 revoked를 돌려주므로 unknown의 의미 자체가 달라집니다. 실제로 이 도구를 열게 되는 질문들에도 답합니다. 이 응답이 아직 유효한가 — thisUpdate와 nextUpdate를 화면에 표시된 기준 시각과 비교하고, nextUpdate가 없으면 "대체될 때까지 유효"라고 분명히 말합니다. 응답기가 내 논스를 돌려줬는가 — 보낸 요청을 붙여넣으면 두 값을 비교합니다. 스테이플링을 디버깅할 때 가장 자주 부딪히는 놀라움이 바로 논스가 사라지는 경우입니다. CA가 직접 서명했는가, 위임 응답기가 서명했는가 — 동봉된 인증서의 공개키를 해시해 CertID의 issuerKeyHash와 맞춰 보고, 위임 응답기인데 id-kp-OCSPSigning이 없으면 경고합니다. 한계도 분명히 밝힙니다. CertID는 발급자 이름과 키의 해시에 일련번호를 더한 것이라 주체 이름으로 되돌릴 수 없고, 서명 검증은 발급자 공개키가 필요한데 이 페이지에는 없습니다. 즉 여기 보이는 것은 바이트가 말하는 내용이지 신뢰 판단이 아닙니다.
사용법
- .der 파일을 놓거나, 응답을 base64·PEM·16진수 덤프로 붙여넣으세요. 모든 해석은 페이지 안에서 이뤄집니다.
- 먼저 응답 상태를 확인하세요. successful이 아니면 서명도 없고 인증서 상태도 담기지 않은, 그 자체로 완결된 응답입니다.
- 인증서 상태 표에서 good·revoked·unknown과 thisUpdate·nextUpdate, 폐기된 경우 폐기 시각과 사유를 읽으세요.
- 신선도 줄과 그 옆의 기준 시각을 보세요. nextUpdate가 지난 응답은 규격을 지키는 클라이언트라면 거부합니다.
- 마지막 칸에 보낸 요청을 붙여넣어 논스가 되돌아왔는지 확인하고, 인증서 항목에서 위임 응답기가 id-kp-OCSPSigning을 가졌는지 보세요.
자주 묻는 질문
- 응답이 6바이트뿐인데 잘린 걸까요?
- 대개 아닙니다. OCSPResponse는 첫 필드가 상태인 SEQUENCE이고, 뒤따르는 응답 바이트는 상태가 successful일 때만 존재합니다. 따라서 malformedRequest, internalError, tryLater, sigRequired, unauthorized는 5~6바이트로 완결된 응답이며 서명도 producedAt도 없고 어떤 인증서도 언급하지 않습니다. 특히 tryLater는 부하가 걸린 응답기가 돌려주는 값이라 클라이언트는 실패로 처리하지 말고 다시 시도해야 합니다. 스테이플링용으로 응답을 저장한다면 이런 응답을 저장하는 것 자체가 버그입니다.
- CertID는 왜 아직도 SHA-1을 쓰나요? 취약점 아닌가요?
- 인증이 아니라 식별에 쓰이기 때문입니다. CertID는 발급자 이름 해시, 발급자 공개키 해시, 인증서 일련번호로 이뤄진 조회 키일 뿐이고, 돌아온 답을 지키는 것은 응답 전체에 대한 서명이지 이 해시가 아닙니다. 충돌 공격을 하려면 이름 해시와 키 해시가 같고 일련번호까지 같은 다른 발급자가 필요한데, 그렇게 얻는 것이 공격자에게 별 이득이 없습니다. 그래서 RFC 6960은 이 자리에 여전히 SHA-1을 둡니다. 반면 응답 자체가 SHA-1로 서명되어 있다면 그것은 진짜 문제이고, 이 디코더는 그 경우를 따로 표시합니다.
- nextUpdate가 없으면 언제 만료되나요?
- 형식적으로는 만료되지 않습니다. RFC 6960은 nextUpdate가 없으면 항상 더 새로운 정보가 있다는 뜻이며 대체될 때까지 신뢰할 수 있다고 말합니다. 실제로는 클라이언트마다 자체 상한을 두지만, 파싱만 되면 계속 받아들이는 구현도 많습니다. 재전송 공격이 노리는 구간이 정확히 여기입니다. 논스가 흥미로운 이유도 같습니다. 논스가 있으면 가로챈 응답을 나중 질의에 재사용할 수 없습니다.
- 응답기가 논스를 버렸습니다. 잘못된 응답인가요?
- 아닙니다. 디버깅할 때 가장 자주 겪는 일입니다. 큰 공개 CA는 응답을 미리 대량 생성해 CDN에서 제공하는데, 요청마다 다른 논스를 되돌려주는 방식과는 맞지 않아 아예 넣지 않습니다. RFC 8954도 응답기가 이 확장을 무시할 수 있게 허용합니다. 응답 자체는 유효하고, 다만 그 응답이 내 질의를 위해 만들어졌다는 증거를 잃을 뿐이며 신선도는 thisUpdate와 nextUpdate에 의존하게 됩니다. 요청을 붙여넣으면 논스가 돌아왔는지, 버려졌는지, 아니면 다른 값으로 돌아왔는지 알려 줍니다. 마지막 경우야말로 남의 질의에 대한 답을 보고 있다는 뜻입니다.
- unknown과 아무 말도 하지 않는 응답은 어떻게 다른가요?
- unknown은 분명한 답입니다. 이 응답기에 해당 일련번호 기록이 없다는 뜻이며, 보통 CertID가 가리키는 CA가 아닌 다른 CA가 발급했거나 아예 존재한 적 없는 인증서입니다. good과 같지 않으며 그렇게 다뤄서도 안 됩니다. 이 인증서에 대해서는 답하지 않겠다는 unauthorized와도 다릅니다. extended-revoke 확장이 있는 응답기라면 의미가 더 좁아집니다. 발급한 적 없는 인증서에도 1970년 초를 폐기 시각으로 하는 revoked를 돌려주므로, 그런 응답기의 unknown은 "내 관할이 아니다"에 가깝습니다.
- 어떤 인증서에 대한 응답인지 알려 주거나 서명을 검증할 수 있나요?
- 앞의 것은 불가능하고, 뒤의 것은 일부러 하지 않습니다. CertID는 해시와 일련번호의 묶음이고 해시는 되돌릴 수 없어서, 응답과 인증서를 맞추려면 그 인증서의 발급자 이름과 키를 해시해 비교하는 수밖에 없습니다. 즉 인증서를 이미 가지고 있어야 합니다. 서명 검증은 발급자 공개키가 필요한데 이 페이지는 그것을 가지고 있지도, 가져오지도 않습니다. 다만 바이트만으로도 서명 주체는 가릴 수 있습니다. 동봉된 인증서의 키 해시를 CertID의 issuerKeyHash와 비교하면 발급 CA인지 위임 응답기인지 구분됩니다.
관련 도구
HTTP 상태 코드 레퍼런스
1xx-5xx 모든 HTTP 상태 코드 검색 — 요약·RFC·사용 시점·흔한 함정 포함.
CRL 디코더 (X.509)
인증서 폐기 목록을 브라우저에서 읽습니다. 발급자, CRL 번호, 유효 구간, 폐기된 일련번호와 사유, 서명 검증까지.
CSR 디코더 (PKCS#10)
인증서 서명 요청을 보내기 전에 확인합니다. 주체, SAN, 키 길이, 서명 알고리즘, 그리고 자체 서명이 검증되는지까지.
ASN.1 / DER 디코더
PEM·base64·hex 무엇이든 붙여넣으면 ASN.1 트리를 보여줍니다. 오프셋, 태그, 길이, 해석된 값까지.
CAA 레코드 빌더 (DNS 인증 기관 권한 제한)
CAA (Certificate Authority Authorization) DNS 레코드 생성 — 신뢰하는 CA만 도메인의 TLS 인증서를 발급할 수 있도록 제한.
PKCS#12 키스토어 분석기
.p12/.pfx를 브라우저에서 엽니다. 비밀번호 없이 MAC과 암호 알고리즘을, 입력 후에는 인증서 체인·개인 키·키 일치 여부를 보여줍니다.