【发布时间】:2017-05-31 12:14:20
【问题描述】:
我正在编写一个接受 SSL 连接的服务器。我已生成自签名证书:
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem -subj "/CN=myhostname"
SSL_accept 失败并显示此消息:
140121764049248:error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher:s3_srvr.c:1417:
这是服务器代码的一部分:
sslCtx = (SSL_CTX_new(SSLv23_server_method());
if (!sslCtx){
ERR_print_errors_fp(stderr);
throw runtime_error("SSL_CTX_new failed");
}
ssl = SSL_new(sslCtx);
if (!ssl)
throw runtime_error("SSL_new failed");
if (SSL_CTX_use_PrivateKey_file(sslCtx, keyFile.c_str(),
SSL_FILETYPE_PEM) != 1)
throw runtime_error("Unable to load private key file" + keyFile);
if (SSL_CTX_use_certificate_file(sslCtx, certFile.c_str(),
SSL_FILETYPE_PEM) != 1)
throw runtime_error("Unable to load certificate file" + certFile);
if (SSL_set_fd(ssl, socket) != 1)
throw runtime_error("SSL_set_fd failed");
if (SSL_accept(ssl) != 1){
ERR_print_errors_fp(stderr);
throw runtime_error("SSL_accept failed");
}
我尝试测试服务器:
openssl s_client -cipher RSA -connect myhostname:33221 -tls1 -CApath . -servername myhostname
得到了
CONNECTED(00000003)
139898773520408:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1487:SSL alert number 40
139898773520408:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1496232544
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
我使用的是 OpenSSL 1.0.2g。
【问题讨论】:
-
CN=myhostname可能是错误的。主机名始终位于 SAN 中。如果它出现在 CN 中,那么它也必须出现在 SAN 中(在这种情况下您必须列出两次)。有关更多规则和原因,请参阅 How do you sign Certificate Signing Request with your Certification Authority 和 How to create a self-signed certificate with openssl? 您还需要将自签名证书放在适当的信任库中。 -
请提供您用于连接服务器的 URL,并发布
openssl s_client -connect <hostname>:<port> -tls1 -servername <hostname> | openssl x509 -text -noout的输出。另请参阅 OpenSSL wiki 上的 TLS Client。它向您展示了如何在客户端的上下文中很好地配置SSL_CTX。其中大部分也适用于服务器。此外,这可能会给您带来麻烦:if (SSL_accept(ssl) != 1),尤其是在非阻塞套接字上。我似乎记得非阻塞套接字经常返回-1并且它不是错误。
标签: c++ ssl openssl ssl-certificate