ZeroTool Workbench
CSR 디코더
PKCS#10 인증서 서명 요청을 브라우저에서 디코딩. Subject, 공개 키, 요청된 SAN과 확장을 확인하고 자체 서명을 검증해 CA 제출 전에 문제를 잡아냅니다. 업로드 없음.
CSR 점검 절차
- BEGIN과 END 줄을 포함해 PEM 요청을 붙여넣습니다.
- 디코드를 누르거나 텍스트 영역에서 Ctrl / Cmd + Enter를 누릅니다.
- 제출 전 점검을 먼저 확인합니다. 거절로 이어질 가능성이 높은 순서로 정렬되어 있습니다.
- Subject와 요청된 SAN 목록이 발급받으려는 인증서와 일치하는지 대조합니다. 목록에 있는 이름은 모두 발급 인증서에 들어가고, 빠뜨린 이름은 들어가지 않습니다.
제출 전 점검 기준
| 점검 항목 | CA가 중시하는 이유 |
|---|---|
| 자체 서명 | 소유 증명. 서명이 검증되지 않는 요청은 전송 중 손상되었거나 서로 맞지 않는 조각으로 조립된 것입니다. |
| 키 강도 | CA/Browser Forum 기준 요건의 하한은 RSA 2048비트 또는 256비트 타원 곡선입니다. 그보다 작으면 즉시 거부됩니다. |
| 서명 해시 | SHA-1은 2016년에 공개 발급에서 퇴출되었습니다. SHA-1이나 MD5로 서명한 요청은 제출 즉시 무효입니다. |
| subjectAltName | SAN이 없는 인증서는 아무것도 보호하지 못합니다. 브라우저가 호스트 이름 대조에서 Common Name을 더 이상 읽지 않기 때문입니다. |
| CN의 SAN 포함 | CN을 SAN에도 적지 않으면, 정작 지정한 그 호스트 이름을 보호하지 못하는 인증서가 발급됩니다. |
| 와일드카드 위치 | 와일드카드는 최좌측 레이블 전체로만 유효합니다. *.example.com은 가능하고 api.*.example.com과 w*.example.com은 불가합니다. |
| 공개 확인 가능한 이름 | .local, .internal 같은 내부 접미사, 점 없는 단일 레이블 이름, 사설 IP 대역은 공개 신뢰 인증서에 들어갈 수 없습니다. |
CSR에 담기는 것
PKCS#10 요청의 실체는 DER로 감싼 세 가지입니다. 요청되는 정보, 그것에 서명한 알고리즘, 그리고 서명 자체. 정보 블록에는 Subject 식별명, 공개 키, 선택적 속성 집합이 들어갑니다. 흥미로운 내용은 거의 전부 속성 집합 안에 있으며, extensionRequest 속성이 SAN 목록과 key usage, extended key usage 플래그를 실어 나릅니다.
CSR에 들어 있지 않은 것은 개인 키입니다. 요청 안의 어떤 정보로도 사용자를 사칭할 수 없기에 일반적인 경로로 CA에 보내도 안전합니다. 유일한 예외가 challengePassword로, 일부 CA가 이후 폐기 절차에 쓰는 공유 비밀입니다. 이 디코더는 해당 속성의 존재 여부만 보고하며 값은 의도적으로 표시하지 않습니다.
서명 검증 방식
디코더는 DER에서 CertificationRequestInfo의 바이트 범위를 정확히 잘라내고, 내장된 SubjectPublicKeyInfo를 crypto.subtle.importKey로 가져온 뒤, 요청에 명시된 알고리즘으로 crypto.subtle.verify를 호출합니다. RSA PKCS#1 v1.5, RSA-PSS, 그리고 P-256 / P-384 / P-521 위의 ECDSA가 이 경로로 검증됩니다. ECDSA 서명은 DER의 SEQUENCE{r,s} 형태에서 Web Crypto가 요구하는 고정 길이 배치로 변환됩니다.
Ed25519와 Ed448도 같은 방식으로 시도하며, 성공 여부는 브라우저가 이 알고리즘을 Web Crypto에 노출하는지에 달려 있습니다. 브라우저가 가져오기를 거부하면 점검 항목은 “서명이 잘못됨”이 아니라 “검증할 수 없음”으로 보고합니다. 알고리즘 미지원과 서명 손상은 서로 다른 문제이고 걱정해야 할 것은 후자뿐이기 때문입니다. 이 경우 로컬에서 openssl req -in req.pem -verify -noout로 확인하세요.
SPKI 핀의 쓰임새
요청 지문과 함께, SubjectPublicKeyInfo로 계산한 sha256/… 핀도 출력합니다. 공개 키 피닝 설정에서 쓰는 RFC 7469 형식입니다. 이 값은 키에만 의존하므로 같은 키 쌍으로 발급된 모든 인증서에서 동일하게 유지됩니다. openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64 결과와 맞춰 보면, 받은 인증서가 정말 이 요청에서 발급된 것인지 확인할 수 있습니다.
지원 범위
이 도구가 읽는 것은 PEM 형식의 PKCS#10 요청뿐입니다. 요청을 생성하지 않고, 개인 키를 읽지도 받지도 않으며, 네트워크 통신도 하지 않습니다. 수행하는 점검은 눈앞의 바이트만으로 판정할 수 있는 항목으로 한정됩니다. 인증서 체인 검증, CT 로그 확인, 발급 정책 적용은 CA의 몫이며 로컬 등가 명령은 openssl req -in req.pem -noout -text입니다.
FAQ
CSR이 어딘가로 업로드되나요?
아닙니다. ASN.1 파싱, 해시 계산, 서명 검증이 모두 페이지 내 인라인 JavaScript와 Web Crypto API로 처리되며 요청 본문은 기기를 벗어나지 않습니다. 웹에 있는 CSR 디코더 대부분이 인증서 판매사의 유입 페이지이고 붙여넣은 내용이 그쪽 서버로 전달된다는 점을 감안하면 의미가 있는 차이입니다.
자체 서명 검증은 무엇을 증명하나요?
PKCS#10 요청은 그 안의 공개 키와 짝이 되는 개인 키로 서명됩니다. 이 서명이 검증되면 두 키가 실제로 한 쌍이며 생성 이후 단 1바이트도 바뀌지 않았음이 확인됩니다. CA가 수신 시 수행하는 소유 증명과 동일한 절차이므로 여기서 실패하는 요청은 CA에서도 실패합니다. 원인은 대개 PEM 잘림, 메일 클라이언트의 줄바꿈 재적용, 수작업 편집입니다.
멀쩡해 보이는 CSR을 CA가 거절하는 이유는?
흔한 네 가지 원인을 모두 여기서 검사합니다. RSA 키 2048비트 미만, SHA-1 서명, subjectAltName 전무, Common Name이 SAN에 함께 기재되지 않음입니다. 브라우저는 오래전부터 SAN만으로 호스트 이름을 대조하므로, 호스트 이름을 CN에만 적은 CSR은 어떤 브라우저도 받아들이지 않는 인증서를 만들어 냅니다.
어떤 입력 형식을 지원하나요?
PEM만 지원합니다. -----BEGIN CERTIFICATE REQUEST----- 와 Windows certreq가 출력하는 -----BEGIN NEW CERTIFICATE REQUEST----- 두 형식을 모두 인식합니다. DER 바이너리는 직접 읽지 않으며 openssl req -inform DER -in req.der -out req.pem 로 변환한 뒤 사용하세요.
이 도구로 CSR을 만들 수 있나요?
만들 수 없고, 만들어서도 안 됩니다. CSR 생성은 개인 키 생성을 수반하는데 웹 페이지가 만든 개인 키는 그 페이지가 사본을 남길 수 있는 키입니다. openssl req -new -newkey rsa:2048 -nodes -keyout key.pem -out req.pem 를 로컬에서 실행한 뒤, 생성된 요청을 여기에 붙여넣어 점검하세요.