用于64位Windows的OpenSSL和“不共享密码”

我刚编译并安装了64位Windows的OpenSSL。 我使用以下命令创build了一个自签名证书和一个私钥:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 10000 -nodes 

我现在正在testingOpenSSL Wiki中使用Firefox的“简单TLS服务器”示例以及一些支持Winsock的修改,但是我一直在收到错误

 11216:error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:ssl\statem\statem_srvr.c:1422: 

(第一个数字总是不一样)在执行SSL_accept()函数期间。 我已经在使用Wireshark连接到HTTPS服务器(因为在本地主机上捕获很困难)的情况下,检查了Firefox(v 43.0.1)在其TLS v1.2客户端Hello中发送的(11)密码列表,并将其与支持的通过我的安装OpenSSL(find使用openssl.exe ciphers -s -tls1_2 -V )。 结果是有通用的密码,所以我错过了什么?

包含statem_srvr.c的行1422的块如下,从1420开始:

 if (cipher == NULL) { SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); goto f_err; } 

对原始代码的修改在while循环之前和标题中:

 #pragma comment(lib,"Ws2_32.lib") #include <stdio.h> #include <winerror.h> #include <WinSock2.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/applink.c> 

 int sock; SSL_CTX *ctx; WSADATA WsaDat; if (WSAStartup(MAKEWORD(2, 2), &WsaDat) != 0) perror("Winsock fatal startup error"); init_openssl(); ctx = create_context(); configure_context(ctx); sock = create_socket(4433); 

编辑:这是当我尝试使用s_client与TLSv1.2连接到服务器时会发生什么:

 CONNECTED(000000F0) 23368:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1362:SSL alert number 40 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 176 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: PSK identity: None PSK identity hint: None SRP username: None Start Time: 1473536238 Timeout : 7200 (sec) Verify return code: 0 (ok) Extended master secret: no --- 

事实证明,找到证书和私钥存在问题。 问题解决了。

EJP的评论解决了我的问题。 在我的情况下,我创建了SSL_CTX的SSL对象,但是在创建SSL对象之后,为SSL_CTX设置了证书和密钥,因此证书和密钥从未复制到SSL对象。 移动我的证书和密钥代码之前,我创建我的SSL对象解决了这个问题。

错误的方法:

 /*Create SSL Context*/ SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); /*Create SSL Object*/ SSL *ssl = SSL_new(ctx); /*Load certs into SSL server*/ //<---WRONG; SHOULD NOT BE HERE if (!SSL_CTX_use_certificate_file(ctx, "C:\\Users\\dzmf39\\Documents\\PPH1261726\\TLS\\tls_cert.pem", SSL_FILETYPE_PEM)) { fprintf(stderr, "Error while loading SSL server Certificate.\n"); return 0; } if (!SSL_CTX_use_PrivateKey_file(ctx, "C:\\Users\\dzmf39\\Documents\\PPH1261726\\TLS\\tls_key.pem", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stderr); return 0; } SSL_do_handshake(ssl); //Throws handshake error 

正确的方法

 /*Create SSL Context*/ SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); /*Load certs into SSL server*/ //<---CORRECT; GOES BEFORE SSL object creation if (!SSL_CTX_use_certificate_file(ctx, "C:\\Users\\dzmf39\\Documents\\PPH1261726\\TLS\\tls_cert.pem", SSL_FILETYPE_PEM)) { fprintf(stderr, "Error while loading SSL server Certificate.\n"); return 0; } if (!SSL_CTX_use_PrivateKey_file(ctx, "C:\\Users\\dzmf39\\Documents\\PPH1261726\\TLS\\tls_key.pem", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stderr); return 0; } /*Create SSL Object*/ SSL *ssl = SSL_new(ctx); SSL_do_handshake(ssl); 

还有其他方法可以直接将密钥添加到SSL对象,在这种情况下,这不适用,但我没有去那个路线。