由于返回 SSL3_GET_CLIENT_CERTIFICATE:no 证书,验证 SSL 客户端真实性失败
Verifying SSL client authenticity fails due to SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
我正在为 C++ 使用 OpenSSL API。通信在嵌入式 linux 设备(SSL 服务器)和 Windows 软件(SSL 客户端)之间进行。
我想确保预期的服务器和客户端只会相互通信。我已经为 服务器 生成了根密钥以及以下内容:
- 根 CA(客户端用于授权服务器)
- 服务器证书
- 服务器私钥
仅在握手期间授权服务器证书时,我的 SSL 连接工作正常。
但是,我也想验证客户端的真实性,所以我为 客户端 生成了另一个根密钥,以及以下内容:
- 根 CA(服务器用于授权客户端)
- 客户端证书
- 客户端私钥
使用下面的代码,由于以下错误,我的服务器无法接受客户端连接:
724428760:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:3291:
这是我的与 SSL 证书相关的服务器代码:
bool SSLServer::loadCertificates(const char * sCertFile,
const char * sKeyFile,
const char * sCAFile)
{
// set server certificate
if (SSL_CTX_use_certificate_file(_pCTX, sCertFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
// set the private key
if (SSL_CTX_use_PrivateKey_file(_pCTX, sKeyFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
// verify private key
if (!SSL_CTX_check_private_key(_pCTX))
{
qWarning() << "Private key does not match the public certificate.";
return false;
}
SSL_CTX_set_verify(_pCTX, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
// load the trusted client CA certificate into context
if (SSL_CTX_load_verify_locations(_pCTX, sCAFile, NULL) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// allow this CA to be sent to the client during handshake
STACK_OF(X509_NAME) * list = SSL_load_client_CA_file(sCAFile);
if (NULL == list)
{
qWarning() << "Failed to load SSL client CA file.";
return false;
}
SSL_CTX_set_client_CA_list(_pCTX, list);
SSL_CTX_set_verify_depth(_pCTX, 1);
return true;
}
这是我的客户端代码:
bool SSLClient::LoadCertificates(const char * sCAFile,
const char * sClientCertFile,
const char * sClientKeyFile)
{
ASSERT(NULL != sCAFile && NULL != sClientCertFile && NULL != sClientKeyFile);
// load RSA CA certificate into context to let client verify server's authenticity
// (will be used with server certificate and private key)
if (!SSL_CTX_load_verify_locations(_pCTX, sCAFile, NULL))
{
ERR_print_errors_fp(stderr);
return false;
}
// load client certificate into context to let server verify client's authenticity
// (will be used with server's RSA CA certificate)
if (SSL_CTX_use_certificate_file(_pCTX, sClientCertFile, SSL_FILETYPE_PEM) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// load client certificate private key into context
if (SSL_CTX_use_PrivateKey_file(_pCTX, sClientKeyFile, SSL_FILETYPE_PEM) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// verify that client cert and private key match
if (!SSL_CTX_check_private_key(_pCTX))
{
OutputDebugString("Private key does not match the certificate public key\n");
return false;
}
// require server certificate verification
SSL_CTX_set_verify(_pCTX, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify_depth(_pCTX, 1);
return true;
}
同样,如果我删除与验证客户端证书相关的代码,它会完全正常工作。我是漏掉了什么,还是做错了什么?
您的代码和证书的工作副本:http://files.webfile.ru/567c28b8973091cbdad036f3e43e989b
如果生成证书只需点击 'enter' 回答问题,您的问题就可以重现。您将获得 'self-signed' 证书,但没有任何意图。问题完全像 OpenSSL - error 18 at 0 depth lookup:self signed certificate
当窥探 ssl 问题时,你不应该使用 wireshark,而应该使用 ssldump。
724428760:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:3291:
错误消息具有误导性。虽然它说客户端没有 return 任何证书,但如果客户端发送服务器无法验证的证书,它也会发生。请确保客户端发送的证书实际上可以针对服务器进行验证 sCAFile
.
我正在为 C++ 使用 OpenSSL API。通信在嵌入式 linux 设备(SSL 服务器)和 Windows 软件(SSL 客户端)之间进行。
我想确保预期的服务器和客户端只会相互通信。我已经为 服务器 生成了根密钥以及以下内容:
- 根 CA(客户端用于授权服务器)
- 服务器证书
- 服务器私钥
仅在握手期间授权服务器证书时,我的 SSL 连接工作正常。
但是,我也想验证客户端的真实性,所以我为 客户端 生成了另一个根密钥,以及以下内容:
- 根 CA(服务器用于授权客户端)
- 客户端证书
- 客户端私钥
使用下面的代码,由于以下错误,我的服务器无法接受客户端连接:
724428760:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:3291:
这是我的与 SSL 证书相关的服务器代码:
bool SSLServer::loadCertificates(const char * sCertFile,
const char * sKeyFile,
const char * sCAFile)
{
// set server certificate
if (SSL_CTX_use_certificate_file(_pCTX, sCertFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
// set the private key
if (SSL_CTX_use_PrivateKey_file(_pCTX, sKeyFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
// verify private key
if (!SSL_CTX_check_private_key(_pCTX))
{
qWarning() << "Private key does not match the public certificate.";
return false;
}
SSL_CTX_set_verify(_pCTX, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
// load the trusted client CA certificate into context
if (SSL_CTX_load_verify_locations(_pCTX, sCAFile, NULL) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// allow this CA to be sent to the client during handshake
STACK_OF(X509_NAME) * list = SSL_load_client_CA_file(sCAFile);
if (NULL == list)
{
qWarning() << "Failed to load SSL client CA file.";
return false;
}
SSL_CTX_set_client_CA_list(_pCTX, list);
SSL_CTX_set_verify_depth(_pCTX, 1);
return true;
}
这是我的客户端代码:
bool SSLClient::LoadCertificates(const char * sCAFile,
const char * sClientCertFile,
const char * sClientKeyFile)
{
ASSERT(NULL != sCAFile && NULL != sClientCertFile && NULL != sClientKeyFile);
// load RSA CA certificate into context to let client verify server's authenticity
// (will be used with server certificate and private key)
if (!SSL_CTX_load_verify_locations(_pCTX, sCAFile, NULL))
{
ERR_print_errors_fp(stderr);
return false;
}
// load client certificate into context to let server verify client's authenticity
// (will be used with server's RSA CA certificate)
if (SSL_CTX_use_certificate_file(_pCTX, sClientCertFile, SSL_FILETYPE_PEM) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// load client certificate private key into context
if (SSL_CTX_use_PrivateKey_file(_pCTX, sClientKeyFile, SSL_FILETYPE_PEM) != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
// verify that client cert and private key match
if (!SSL_CTX_check_private_key(_pCTX))
{
OutputDebugString("Private key does not match the certificate public key\n");
return false;
}
// require server certificate verification
SSL_CTX_set_verify(_pCTX, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify_depth(_pCTX, 1);
return true;
}
同样,如果我删除与验证客户端证书相关的代码,它会完全正常工作。我是漏掉了什么,还是做错了什么?
您的代码和证书的工作副本:http://files.webfile.ru/567c28b8973091cbdad036f3e43e989b
如果生成证书只需点击 'enter' 回答问题,您的问题就可以重现。您将获得 'self-signed' 证书,但没有任何意图。问题完全像 OpenSSL - error 18 at 0 depth lookup:self signed certificate 当窥探 ssl 问题时,你不应该使用 wireshark,而应该使用 ssldump。
724428760:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:3291:
错误消息具有误导性。虽然它说客户端没有 return 任何证书,但如果客户端发送服务器无法验证的证书,它也会发生。请确保客户端发送的证书实际上可以针对服务器进行验证 sCAFile
.