openssl을 사용하여 서버에서 인증서 가져 오기


353

원격 서버의 인증서를 얻으려고하는데 키 저장소에 추가하고 Java 응용 프로그램 내에서 사용할 수 있습니다.

선임 개발자 (휴일 :()는 내가 이것을 실행할 수 있다고 알려줍니다.

openssl s_client -connect host.host:9999

원시 인증서를 덤프하려면 복사하여 내보낼 수 있습니다. 다음과 같은 결과가 나타납니다.

depth=1 /C=NZ/ST=Test State or Province/O=Organization Name/OU=Organizational Unit Name/CN=Test CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
23177:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1086:SSL alert number 40
23177:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:

나는 또한이 옵션으로 시도했다

-showcerts 

그리고 이것은 (데비안 마음에서 실행)

-CApath /etc/ssl/certs/ 

그러나 같은 오류가 발생합니다.

이 소스 는 해당 CApath 플래그를 사용할 수 있지만 도움이되지 않는 것 같습니다. 나는 쓸모없는 여러 경로를 시도했다.

내가 잘못 가고있는 곳을 알려주십시오.

답변:


461

SNI로

원격 서버가 SNI를 사용하는 경우 (즉, 단일 IP 주소에서 여러 SSL 호스트를 공유하는 경우) 올바른 인증서를 얻으려면 올바른 호스트 이름을 보내야합니다.

openssl s_client -showcerts -servername www.example.com -connect www.example.com:443 </dev/null

SNI없이

원격 서버가 SNI를 사용하지 않는 경우 -servername매개 변수 를 건너 뛸 수 있습니다 .

openssl s_client -showcerts -connect www.example.com:443 </dev/null


사이트 인증서의 전체 세부 정보를 보려면이 명령 체인도 사용할 수 있습니다.

$ echo | \
    openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | \
    openssl x509 -text

3
흠. 해당 명령을 시도 할 때 여전히 동일한 오류가 발생합니다. Openssl 버전이 'OpenSSL 0.9.8g 2007 년 10 월 19 일'인 것으로 나타났습니다. 당신은 어떤 아이디어가 있습니까?
불쾌한 페이스트리

39
유용한 : echo "" | openssl s_client -connect server:port -prexit 2>/dev/null | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p' stackoverflow.com/a/12918442/843000
mbrownnyc

16
madboa.com의 유용한 대체 스크립트 :echo | openssl s_client -connect server:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cert.pem
rmeakins

9
이 좀 더 간결하게하려면, 당신은을 대체 할 수 sedopenssl x509하고, 하위 쉘을 사용하여 읽어 :openssl x509 -in <(openssl s_client -connect server:port -prexit 2>/dev/null)
게이브 마틴 - Dempesy

27
또한echo | openssl s_client -connect google.com:443 2>/dev/null | openssl x509
MattSizzle

68

Ari의 답변에 동의하고 (공개했습니다 :) Windows에서 Java와 함께 작동하려면 추가 단계를 수행해야했습니다 (배포해야 함).

openssl s_client -showcerts -connect www.example.com:443 < /dev/null | openssl x509 -outform DER > derp.der

openssl x509 -outform DER변환을 추가하기 전에 Windows의 keytool에서 인증서 형식에 대해 불평하는 오류가 발생했습니다. .der 파일 가져 오기가 정상적으로 작동했습니다.


이상한. Java 6부터 Windows에서 keytool과 함께 PEM 인증서를 사용해 왔으며 문제가 발생하지 않았습니다.
imgx64 5

39

여기에는 더 복잡한 것이 있습니다.이 롤링을 얻으려면 더 많은 세부 정보를 제공해야했습니다. 클라이언트 인증이 필요한 연결과 행크 쉐이크에는 인증서가 덤프 된 단계로 계속 진행하기 위해 더 많은 정보가 필요하다는 사실과 관련이 있다고 생각합니다.

작업 명령은 다음과 같습니다.

openssl s_client -connect host:port -key our_private_key.pem -showcerts \
                 -cert our_server-signed_cert.pem

잘하면 이것은 더 많은 정보로 할 수있는 사람에게 올바른 방향으로 조금씩 움직입니다.


6
죄송하지만 귀하의 답변은 이해가되지 않습니다. 인증서를 받으려면 서버로 인증서를 전달해야합니까?
Ari Maniatis

2
네. 클라이언트 인증 AFAIK.
불쾌한 페이스트리

11
'-prexit'은 해당 데이터도 반환합니다. 예를 들어; openssl s_client-연결 호스트 : 포트 -prexit
Robert

39

이번에는 다음을 사용하여 PEM 형식의 원격 서버에서 인증서를 추출하는 단일 라이너 sed.

openssl s_client -connect www.google.com:443 2>/dev/null </dev/null |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

2
이것은 인증서를 추출하는 데 거의 완벽하며 -servername옵션을 누락하고 이유를 모르지만 전체 인증서를 얻으려면 인증서를 사용해야했습니다.
Karl.S

-servername은 서버 이름 표시 (SNI)에 필요합니다. 웹 검색은 나머지에서 확장 될 수 있습니다.
Sam Gleske

32

키 저장소에 추가 할 수있는 PEM 출력과 사람이 읽을 수있는 출력을 포함하고 SNI를 지원하는 가장 쉬운 명령 줄은 HTTP 서버로 작업하는 경우 중요합니다.

openssl s_client -servername example.com -connect example.com:443 \
    </dev/null 2>/dev/null | openssl x509 -text

-servername 옵션은 SNI를 지원하고 활성화하는 것입니다 있는 OpenSSL에서는 X509 -text 사람이 읽을 수있는 형식으로 인쇄 인증서를.


example.com 대신 ws.example.com과 같이 하위 서버를 -servername에 추가 할 수 있습니다 (이를 -connect 매개 변수에도 적용).
russellhoff

24

원격 서버의 인증서를 얻으려면 당신이 사용할 수있는 openssl도구를 당신이 사이를 찾을 수 BEGIN CERTIFICATE하고 END CERTIFICATE있는 당신이 복사하여 인증서 파일 (CRT)에 붙여 넣어야합니다.

이를 보여주는 명령은 다음과 같습니다.

ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq > file.crt

체인에서 모든 인증서를 반환하려면 g다음과 같이 (전역)을 추가하십시오 .

ex +'g/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq

그런 다음 인증서 파일 ( file.crt)을 키 체인으로 가져 와서 신뢰할 수있게하면 Java가 불평하지 않아야합니다.

OS X에서는 파일을 두 번 클릭하거나 키 체인 액세스를 끌어다 놓아 로그인 / 인증서에 나타납니다. 그런 다음 가져온 인증서를 두 번 클릭하고 SSL을 항상 신뢰하십시오 .

CentOS 5에서는 /etc/pki/tls/certs/ca-bundle.crt파일에 파일을 추가 (및 실행 sudo update-ca-trust force-enable)하거나 CentOS 6에서 복사하여 /etc/pki/ca-trust/source/anchors/실행할 수 sudo update-ca-trust extract있습니다.

우분투에서 복사하여 /usr/local/share/ca-certificates실행하십시오 sudo update-ca-certificates.


12
HOST=gmail-pop.l.google.com
PORT=995

openssl s_client -servername $HOST -connect $HOST:$PORT < /dev/null 2>/dev/null | openssl x509 -outform pem

6

서버의 인증서가 아닌 인증서 체인 만 인쇄하려면 :

# MYHOST=myhost.com
# MYPORT=443
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}'

CentOS / RHEL 6/7에서 CA 신뢰를 업데이트하는 방법 :

# update-ca-trust enable
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >/etc/pki/ca-trust/source/anchors/myca.cert
# update-ca-trust extract

CentOS / RHEL 5에서 :

# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >>/etc/pki/tls/certs/ca-bundle.crt

정확히 CentOS7에 필요한 것. 감사!
Arthur Hebert

5

다음 bash 스크립트를 사용하여 서버 루트 인증서를 가져오고 저장할 수 있습니다.

CERTS=$(echo -n | openssl s_client -connect $HOST_NAME:$PORT -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
echo "$CERTS" | awk -v RS="-----BEGIN CERTIFICATE-----" 'NR > 1 { printf RS $0 > "'$SERVER_ROOT_CERTIFICATE'"; close("'$SERVER_ROOT_CERTIFICATE'") }'

필요한 변수를 덮어 쓰십시오.


4

서버가 전자 메일 서버 (MS Exchange 또는 Zimbra) 인 경우 starttlssmtp플래그 를 추가해야합니다 .

openssl s_client -starttls smtp -connect HOST_EMAIL:SECURE_PORT 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > CERTIFICATE_NAME.pem

어디,

  • HOST_EMAIL 은 서버 도메인입니다 (예 : mail-server.com).

  • SECURE_PORT 는 통신 포트입니다 (예 : 587 또는 465).

  • CERTIFICATE_NAME 출력 파일 이름 (BASE 64 / PEM 형식)


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.