Linux의 인증서 체인에서 루트 CA와 하위 CA를 추출하는 방법은 무엇입니까?

Linux의 인증서 체인에서 루트 CA와 하위 CA를 추출하는 방법은 무엇입니까?

중간 및 루트 인증서가 있는 최종 엔터티/서버 인증서가 있습니다. 최종 cat엔터티 인증서에는 단일 BEGINEND태그만 표시됩니다. 유일한 최종 엔터티 인증서입니다.

중간 및 루트 인증서 내용을 볼 수 있는 방법이 있습니까? 내용 BEGINEND태그만 필요합니다.

Windows에서는 "인증 경로"에서 전체 인증서 체인을 볼 수 있습니다. 다음은 Stack Exchange 인증서의 예입니다.

여기에 이미지 설명을 입력하세요

거기에서 나는 다음을 수행할 수 있습니다.인증서 보기그리고 내보냅니다. Windows의 루트와 중간 모두에 대해 그렇게 할 수 있습니다. 나는 Linux에서도 이와 동일한 방법을 찾고 있습니다.

여기에 이미지 설명을 입력하세요

답변1

웹사이트에서 다음을 수행할 수 있습니다.

openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null

그러면 인증서 체인과 서버가 제공한 모든 인증서가 표시됩니다.

이제 두 인증서를 파일에 저장하면 다음을 사용할 수 있습니다 openssl verify.

$ openssl verify -show_chain -untrusted dc-sha2.crt se.crt 
se.crt: OK
Chain:
depth=0: C = US, ST = NY, L = New York, O = "Stack Exchange, Inc.", CN = *.stackexchange.com (untrusted)
depth=1: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA (untrusted)
depth=2: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA

-untrusted옵션은 중간 인증서를 제공하는 데 사용됩니다. se.crt확인하는 인증서입니다. 깊이=2 결과는 시스템의 신뢰할 수 있는 CA 저장소에서 나왔습니다.

중간 인증서가 없으면 확인을 수행할 수 없습니다. 이것이 바로 X.509가 작동하는 방식입니다.

인증서에 따라 중간 항목을 가져올 URI가 포함될 수 있습니다. 예를 들어 다음이 openssl x509 -in se.crt -noout -text포함됩니다.

        Authority Information Access: 
            OCSP - URI:http://ocsp.digicert.com
            CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt

openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem해당 "CA 발급자" URI는 중간 인증서(DER 형식이므로 OpenSSL에서 나중에 사용하려면 변환하는 데 사용해야 함)를 가리킵니다 .

실행하면 시스템 루트 CA 저장소에서 찾을 수 있는 가 표시됩니다 openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash( 이름 에 추가하기만 하면 됩니다).244b5494/etc/ssl/certs/244b5494.0.0

나는 이 모든 작업을 수행할 수 있는 훌륭하고 쉬운 OpenSSL 명령이 없다고 생각합니다.

답변2

tl;dr - 체인의 모든 인증서를 덤프하는 하나의 라이너 bash 마법

openssl s_client -showcerts -verify 5 -connect wikipedia.org:443 < /dev/null |
   awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
for cert in *.pem; do 
        newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
        echo "${newname}"; mv "${cert}" "${newname}" 
done

2단계 설명

체인의 모든 인증서를 현재 디렉토리에 덤프하려면 다음과 같이 하십시오 cert${chain_number}.pem.

openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null |
 awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}' 

이름을 일반 이름으로 바꾸는 보너스 트랙:

for cert in *.pem; do 
   newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
   mv $cert $newname 
done

답변3

-verify 5openssl 옵션을 사용하면 인증서 배포에 포함되지 않은 인증서도 포함하여 모든 인증서를 표시하는 체인 깊숙이 들어가고 있음을 알았습니다 .

인증서와 함께 어떤 체인이 제공되는지 정말로 이해하려면 다음을 실행해야 합니다.

openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less

답변4

Lets Encrypt 무료 와일드카드 인증서를 사용할 때 위의 내용이 작동하지 않았습니다.

더 구체적으로 말하자면,
*.mydomain.dev에 대해 Lets Encrypt 무료 와일드카드 인증서를 사용하여 구성된 Kubernetes 클러스터 + 수신 컨트롤러가 있으며 다음 2개의 도메인 이름을 호스팅하고 있습니다.

  • grafana.mydomain.dev
  • prometheus.mydomain.dev

이 사이트에 따라 -servername 플래그를 추가해야 했습니다.https://community.letsencrypt.org/t/where-can-i-download-the-trusted-root-ca-certificates-for-lets-encrypt/33241/2

export DOMAIN=grafana.mydomain.dev
openssl s_client -showcerts -verify 5 -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'

또한 표준 출력에 대한 전체 인증서 + 중간 + 루트를 제공하고 표준 오류 노이즈를 숨길 수 있도록 체인을 조정했습니다.

실제로... 테스트할 때 이것이 CA를 제공하지 않는다는 것을 알았습니다... openssl s_client -showcerts -verify 5 -connect letsencrypt.org:443 < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'

curl https://letsencrypt.org/certs/isrgrootx1.pem 다른 값을 제공합니다(일부 항목을 테스트할 때 이것이 작동하는 값입니다.)

관련 정보