64 位 Windows 和 "no shared cipher" 的 OpenSSL
OpenSSL for 64-bit Windows and "no shared cipher"
我刚刚编译并安装了 64 位 OpenSSL Windows。我已经使用以下命令创建了一个自签名证书和一个私钥:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 10000 -nodes
我现在正在使用 Firefox 测试在 OpenSSL Wiki 上找到的 "Simple TLS Server" example 以及一些支持 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 Client Hello 中发送的(11)个密码列表(因为在本地主机上捕获很困难)并将其与支持的密码进行比较通过我安装的 OpenSSL(使用 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循环之前和header中:
#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_CTX 我创建了 ssl 对象之后设置了证书和密钥,所以证书并且密钥从未复制到 SSL 对象。将我的证书和密钥代码移动到 before 我创建了我的 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 对象,在这种情况下不适用,但我没有采用那种方法。
我也遇到了同样的问题。我也解决了:
berofe(那是错误)
SSL_CTX_new
SSL_new
SSL_CTX_use_certificate_chain_file
SSL_CTX_use_PrivateKey_file
之后(没关系)
SSL_CTX_new
SSL_CTX_use_certificate_chain_file
SSL_CTX_use_PrivateKey_file
SSL_new
我刚刚编译并安装了 64 位 OpenSSL Windows。我已经使用以下命令创建了一个自签名证书和一个私钥:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 10000 -nodes
我现在正在使用 Firefox 测试在 OpenSSL Wiki 上找到的 "Simple TLS Server" example 以及一些支持 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 Client Hello 中发送的(11)个密码列表(因为在本地主机上捕获很困难)并将其与支持的密码进行比较通过我安装的 OpenSSL(使用 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循环之前和header中:
#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_CTX 我创建了 ssl 对象之后设置了证书和密钥,所以证书并且密钥从未复制到 SSL 对象。将我的证书和密钥代码移动到 before 我创建了我的 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 对象,在这种情况下不适用,但我没有采用那种方法。
我也遇到了同样的问题。我也解决了:
berofe(那是错误)
SSL_CTX_new
SSL_new
SSL_CTX_use_certificate_chain_file
SSL_CTX_use_PrivateKey_file
之后(没关系)
SSL_CTX_new
SSL_CTX_use_certificate_chain_file
SSL_CTX_use_PrivateKey_file
SSL_new