客户问好后的握手失败

时间:2016-07-16 12:52:13

标签: c++ mysql ssl openssl

我开发了一个由C ++和OpenSSL开发的app来监控MySQL数据包。我的应用程序充当代理。在没有SSL连接的情况下一切正常但是当我使用SSL连接时,它在接收到客户端Hello后正好面临“握手失败”。

我使用openssl开发了一个ssl服务器并使其阻塞,并在正确的时间等待接受ssl连接。

Wireshark截图

Wireshark Screenshot Openssl输出:

  

140167999850080:错误:1408A0C1:SSL例程:SSL3_GET_CLIENT_HELLO:无共享密码:s3_srvr.c:1352:

     

140167999850080:错误:1408A0C1:SSL例程:SSL3_GET_CLIENT_HELLO:无共享密码:s3_srvr.c:1352:

已编辑:这是在检测到ssl连接选项为On时与客户端进行交互的代码的一部分。收到登录请求数据包后,此代码将运行。

void mysqlNegotiation(X509* cert, EVP_PKEY* key, int fd) {
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    SSL_CTX* context = SSL_CTX_new(TLSv1_server_method());

    SSL_CTX_use_certificate(context, cert);
    SSL_CTX_use_PrivateKey(context, key);
    SSL_CTX_check_private_key(context);

    SSL_CTX_set_ecdh_auto(context, 1);
    SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    SSL_CTX_set_verify_depth(context, 4);
    SSL_CTX_load_verify_locations(context, "ca-cert.pem", "/etc/mysql/");

    SSL* ssl = SSL_new(context);
    SSL_set_fd(ssl, fd);

    int r = SSL_accept(ssl);
    if (r != 1) {
        ERR_print_errors_fp(stderr);
        int err_SSL_get_error = SSL_get_error(ssl, r);

        switch (err_SSL_get_error) {
            case SSL_ERROR_NONE:
                printf("%d", 0);
                break;
            case SSL_ERROR_SSL:
                printf("%d", 1);
                break;
            case SSL_ERROR_WANT_READ:
                printf("%d", 2);
                break;
            case SSL_ERROR_WANT_WRITE:
                printf("%d", 3);
                break;
            default:
                printf("%d", -1);
                break;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

此错误可能有多种原因,如上所述,这表明客户端和服务器没有实现可以协商的公共密码。一些原因是:

  1. TLS协议级别不匹配。例如,您可能通过SSLv23_method使用SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1设置SSL_CTX_set_options(),表示仅支持TLS 1.2或更高版本,但客户端不支持高于TLS 1.1的任何内容。这只是一个例子,协议不匹配也可以通过许多其他方式发生。

  2. 通过SSL_CTX_set_cipher_list()配置的SSL密码列表不包含对等方支持的任何密码。

  3. SSL上下文未使用DH参数初始化,因此不支持forward secrecy,并且对等体仅支持支持前向保密的密码。

  4. 也可能有其他原因。如果不检查客户端和服务器的配置,则无法提供权威答案。由于只有您可以访问客户端和服务器的代码,因此您可以自行查明。这里唯一真正的答案是:找到另一个适用于您的客户端的服务器代码,并查看其代码,以确定它与您的代码的不同之处。

答案 1 :(得分:1)

一个常见的错误是你的中间应用程序中的人没有设置任何证书,这意味着不能使用需要身份验证的密码,即可能是客户端提供的所有密码。然后,这导致没有共享密码"警告作为对ClientHello的响应。当然这只是猜测,因为你的中间代理人的代码是未知的。

如果此推测错误,我建议您提供更多信息,即create a Minimal, Complete, and Verifiable example,以便其他人可以实际查看您的设置详情,甚至可以重现您的问题。