나는 클라이언트 인증서 문제로 어려움을 겪고 있으며 누군가가 나를 도울 수 있기를 바랍니다. 부스트 asio를 사용하여 클라이언트/서버 쌍을 개발하고 있지만 비특이적이되도록 노력할 것입니다. 나는 창문에 있고 openssl 1.0.1e를 사용하고있다.OpenSSL 클라이언트가 클라이언트 인증서를 보내지 않음
기본적으로 나는 클라이언트 인증서를 사용하여 클라이언트 인증을 원한다. 서버는 내 CA가 서명 한 인증서가있는 클라이언트 만 수락해야합니다. 그래서 저는 자체 서명 된 CA를 설정했습니다. 이 인증서는 두 개 더 발급되었습니다. 하나는 클라이언트 용이고 다른 하나는 서버 용입니다. 둘 다 CA에서 서명했습니다. 나는 지금까지 꽤 많은 시간을 보냈으며 나는 그것을 얻었다고 확신한다.
내 서버 쪽도 문제가 없습니다. 그것은 클라이언트 인증서를 요청하고 s_client를 사용하고 있다면 그 인증서를 모두 제공합니다. 또한 브라우저를 사용하고 루트 CA를 트러스트 된 것으로 설치 한 다음 클라이언트 인증서를 가져 오는 경우에도 마찬가지입니다.
내가 일할 수없는 유일한 점은 libssl 클라이언트입니다. 내가 디버깅 도구로하지만 같은 일이 발생 내 실제 서버에 대해이 s_server을 사용하고
$ openssl.exe s_server -servername localhost -bugs -CAfile myca.crt -cert server.crt
-cert2 server.crt -key private/server.key -key2 private/server.key -accept 8887 -www
-state -Verify 5
verify depth is 5, must return a certificate
Setting secondary ctx parameters
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
SSL3 alert read:warning:no certificate
SSL3 alert write:fatal:handshake failure
SSL_accept:error in SSLv3 read client certificate B
SSL_accept:error in SSLv3 read client certificate B
2675716:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a
certificate:s3_srvr.c:3193:
ACCEPT
: 나는 그것이 클라이언트있는 Certficate를 전송하지 않습니다 볼 수 있듯이 그것은 항상 악수까지하는 동안 실패합니다. s_client는 동일한 인증서로 정상적으로 작동합니다. 또한 서버에서 "-Verify"를 비활성화하면 연결이 작동합니다. 따라서 클라이언트가 인증서를 보내지 않으려 고하는 것 같습니다. 그 이유가 무엇일까요?
내가 코드를 래퍼가 SSL로 부스트 ASIO를 사용하고 있기 때문에는 다음과 같습니다
SSL_CTX *ctx = m_ssl_context.impl();
SSL *ssl = m_ssl_socket.impl()->ssl;
int res = 0;
res = SSL_CTX_use_certificate_chain_file(ctx, "myca.crt");
if (res <= 0) {
// handle error
}
res = SSL_CTX_use_certificate_file(ctx, "testclient.crt", SSL_FILETYPE_PEM);
if (res <= 0) {
// handle error
}
res = SSL_CTX_use_PrivateKey_file(ctx, "testclient.key", SSL_FILETYPE_PEM);
if (res <= 0) {
// handle error
}
을 :
m_ssl_context.set_verify_mode(asio::ssl::context::verify_peer);
m_ssl_context.load_verify_file("myca.crt");
m_ssl_context.use_certificate_file("testclient.crt", asio::ssl::context::pem);
m_ssl_context.use_private_key_file("testclient.key", asio::ssl::context::pem);
나는 또한 ASIO 무시하고 말하여 SSL 컨텍스트를 직접 액세스하는 것을 시도했다
나는 행동의 차이를 볼 수 없다. 내가 업데이트 할 수없는 매우 오래된 부스트 1.43 asio를 사용하고 있다고 언급해야한다.하지만 모든 관련 호출이 OpenSSL에 직접 또는 간접적으로 적용된다고 가정하고 서버는 그 버전으로 잘 작동하므로 내가 배제 할 수 있다고 생각한다.
클라이언트와 서버를 특정 버전으로 강제 시작하면 오류 메시지가 변경되지만 작동하지 않으며 항상 s_client 테스트와 함께 작동합니다. 나는에 게시 된 이전 버그 항목을 발견
...
SSL_accept:SSLv3 read client key exchange A
<<< TLS 1.0 ChangeCipherSpec [length 0001]
01
<<< TLS 1.0 Handshake [length 0010], Finished
14 00 00 0c f4 71 28 4d ab e3 dd f2 46 e8 8b ed
>>> TLS 1.0 Alert [length 0002], fatal unexpected_message
02 0a
SSL3 alert write:fatal:unexpected_message
SSL_accept:failed in SSLv3 read certificate verify B
2675716:error:140880AE:SSL routines:SSL3_GET_CERT_VERIFY:missing verify
message:s3_srvr.c:2951:
2675716:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure:s3_pkt.c:989:
ACCEPT
: 내가 거기에 클라이언트와 서버 결국 사이 더 수다가 나는 오류가 예를 들어 TLSv1의로 전환하면 현재 그것은 TLSv1의
로 설정 이것에 대해 언급 한 openssl 메일 링리스트. 2 년 전에 해결 된 핸드 셰이크의 틀린 CRLF가 분명히 있습니다. 또는 그것을 가지고 있습니까?
나는 거의 일주일 동안 이것을 디버깅 해왔다. 그리고 나는 정말로 붙어있다. 누구든지 시도 할 것을 제안합니까? 여기에 위의 s_server 디버그 아웃 s_client가 같은있는 Certficate 함께 할 것 인 것이다 : 나는 ... 아이디어에서
건배, 스테판
PS 해요
$ openssl s_client -CAfile ca.crt -cert testclient.crt -key private/testclient.key -verify 2 -connect myhost:8887
ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
depth=1 C = DE, // further info
verify return:1
depth=0 C = DE, // further info
verify return:1
SSL_accept:SSLv3 read client certificate A
SSL_accept:SSLv3 read client key exchange A
SSL_accept:SSLv3 read certificate verify A
SSL_accept:SSLv3 read finished A
SSL_accept:SSLv3 write session ticket A
SSL_accept:SSLv3 write change cipher spec A
SSL_accept:SSLv3 write finished A
SSL_accept:SSLv3 flush data
ACCEPT
을 ... 핸드 셰이크가 완료되고 데이터가 전송됩니다.
불행히도 나는 이미 생각해 낼 수있는 모든 조합을 시도해 보았습니다. 이것 하나 포함. 아무 소용이 없다. 클라이언트가 자신의 클라이언트 인증서를 신뢰하지 않고 보내지 않는 것처럼 보입니다. 이 조합을 사용하면 클라이언트는 전혀 인증서를 보내지 않습니다. 체인 파일을 사용하면 자신의 루트 CA 대신 루트 CA를 보내는 것처럼 보입니다. –
루트 CA를 보내는 경우에는 CA 인증서 만있는 SSL_CTX_use_certificate_chain_file()을 호출하기 때문입니다. 클라이언트 인증서 만 포함 된 파일을 SSL_CTX_use_certificate_chain_file()에 전달할 수 있습니까? –
모든 의견을 보내 주셔서 감사합니다! 매우 감사! @Remi : 이렇게하면 클라이언트가 인증서를 보내지 않습니다. 그것이 제가 설명한 첫 번째 사례입니다. 체인 파일에 CA 인증서 만 포함되어있는 경우도 마찬가지입니다. 나는 그것이 합리적이지는 않지만 어쨌든 시도하고 싶었다. –