【问题标题】:OpenSSL for 64-bit Windows and "no shared cipher"适用于 64 位 Windows 和“无共享密码”的 OpenSSL
【发布时间】:2017-01-18 14:24:02
【问题描述】:

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

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) 密码列表(因为在 localhost 上捕获很困难)并将其与支持的密码进行比较通过我安装的 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);

编辑:当我尝试使用带有 TLSv1.2 的 s_client 连接到服务器时会发生这种情况:

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
---

【问题讨论】:

  • 您能否使用 openssl 本身连接到您的本地服务器?它与什么密码相关联? openssl s_client -connect localhost:4433 -tls1_2
  • 不,我得到了同样的错误。我将发布客户端程序的输出。
  • @JasonHoetger - 他在一台 Windows 机器上。他可能需要使用 TLS 1.0 而不是 1.2(SChannel 在可能的 Windows 版本中缺少 TLS 1.2)。 @Æðelstan - 试试openssl s_client -connect localhost:4433 -tls1 -servername localhost-servername 加入 SNI,这是 TLS 1.0 及更高版本的功能。 4096 位密钥也可能是个问题。许多版本的 Windows 只能处理 2048 位密钥。
  • 感谢您的意见;不幸的是,我遇到了同样的错误。
  • 此消息可能意味着服务器找不到自己的私钥和证书,并且“无对等证书”消息支持该猜想。

标签: windows ssl openssl x509 pkix


【解决方案1】:

事实证明,查找证书和私钥时出现问题。问题解决了。

【讨论】:

    【解决方案2】:

    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 对象,在这种情况下这不适用,但我没有走那条路。

    【讨论】:

      【解决方案3】:

      我也遇到了同样的问题。我也解决了:

      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
      

      【讨论】:

        猜你喜欢
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 2012-10-17
        • 1970-01-01
        • 2013-03-15
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        相关资源
        最近更新 更多