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

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

중간 및 루트 인증서가 포함된 최종 엔터티/서버 인증서가 있습니다. cat최종 엔터티 인증서에는 및 레이블만 표시 BEGIN됩니다 END. 유일한 최종 엔터티 인증서입니다.

중간 및 루트 인증서 내용을 볼 수 있는 방법이 있습니까? 난 그냥 BEGIN내용을 필요로하고 라벨을 지정합니다 END.

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 무료 와일드카드 인증서를 사용할 때 위 방법이 작동하지 않습니다.

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

  • 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}'

또한 체인을 조정하여 stdout의 전체 인증서+중간+루트를 제공하고 stderr 노이즈를 숨깁니다.

실제로... 테스트하는 동안 이것이 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 다른 값을 지정하십시오. (무언가를 테스트할 때 유효한 값입니다.)

관련 정보