密码套件错误或与OpenSSL服务器没有连接
Wrong cipher suite or no connection with OpenSSL server
生成密钥
生成证书openssl ecparam -param_enc named_curve - secp521r1 -genkey -outform PEM -out key.pem
openssl req -x509 -new -key key。pem -keyform pem -out pem .pem -outform pem -days 3650
使用
openssl s_server -accept 5000 -key key.pem -cert ca.pem -tls1_2 -www
可以使用
连接openssl s_client -host 10.8.0.26 -port 5000
客户端告诉我它使用
协议:TLSv1.2密码:ECDHE-ECDSA-AES256-GCM-SHA384
正是我想要的
当我编译并使用下面的c代码启动服务器 时用 编译的g++ Main2.cpp -ldl -lcrypto -lssl -o Main)
#include <iostream>
#include <string>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"
using namespace std;
void Servlet(SSL* ssl) /* Serve the connection -- threadable */
{ char buf[1024];
char reply[1024];
int sd, bytes, err;
const char* HTMLecho="<html><body><pre>%s</pre></body></html>nn";
err = SSL_accept(ssl);
if ( err <= 0 ) { /* do SSL-protocol accept */
printf("%dn",err);
ERR_print_errors_fp(stderr);
}
else
{
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
if ( bytes > 0 )
{
buf[bytes] = 0;
printf("Client msg: "%s"n", buf);
sprintf(reply, HTMLecho, buf); /* construct reply */
SSL_write(ssl, reply, strlen(reply)); /* send reply */
}
else
ERR_print_errors_fp(stderr);
}
sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */
close(sd); /* close connection */
}
int OpenListener(int port)
{ int sd;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
inet_aton("10.8.0.26", &addr.sin_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
//addr.sin_addr.s_addr = INADDR_ANY;
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
perror("can't bind port");
abort();
}
if ( listen(sd, 10) != 0 )
{
perror("Can't configure listening port");
abort();
}
return sd;
}
int main(int argc, const char* argv[]) {
//SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
cout << SSLeay_version(SSLEAY_VERSION) << endl;
SSL_CTX *ctx;
const SSL_METHOD *method;
method = TLSv1_2_server_method();
//method = SSLv23_server_method();
ctx = SSL_CTX_new(method); /* create new context from method */
if ( ctx == NULL )
{
ERR_print_errors_fp(stderr);
abort();
}
if (SSL_CTX_set_ecdh_auto(ctx, 1) != 1)
ERR_print_errors_fp(stderr);
//if (SSL_CTX_set_cipher_list(ctx, "ECDH-ECDSA-AES256-GCM-SHA384") != 1)
// ERR_print_errors_fp(stderr);
if (SSL_CTX_load_verify_locations(ctx, "ca.pem", "key.pem") != 1)
ERR_print_errors_fp(stderr);
if (SSL_CTX_set_default_verify_paths(ctx) != 1)
ERR_print_errors_fp(stderr);
if (SSL_CTX_use_certificate_file(ctx, "ca.pem", SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
if (!SSL_CTX_check_private_key(ctx))
{
fprintf(stderr, "Private key does not match the public certificaten");
abort();
}
int server;
server = OpenListener(5000);
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
SSL *ssl;
int client = accept(server, (struct sockaddr*)&addr, &len); /* accept connection as usual */
printf("Connection: %s:%dn",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
ssl = SSL_new(ctx); /* get new SSL state with context */
if (ssl == NULL) {
ERR_print_errors_fp(stderr);
return 0;
}
SSL_set_fd(ssl, client); /* set connection socket to SSL state */
Servlet(ssl); /* service connection */
close(server); /* close server socket */
SSL_CTX_free(ctx); /* release context */
return 0;
}
当我现在使用openssl s_client像上面一样连接时,它使用
协议:TLSv1.2密码:ECDH-ECDSA-AES256-GCM-SHA384
not ECDHE !为什么?
当我使用chrome/firefox连接到openssl s_server或我的服务器代码,我得到:
140675163166384:错误:1408A0C1:SSL例程:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1396:
,当我现在使用openssl s_client连接,就像上面使用
Protocol : TLSv1.2 Cipher : ECDH-ECDSA-AES256-GCM-SHA384
not ECDHE !为什么?
ECDH
和ECDHE
是两种不同的Diffie-Hellman。ECDH
使用固定的服务器密钥。ECDHE
是临时的,它使用临时密钥。您应该使用ECDHE
。
对于ECDHE
,您没有使用SSL_CTX_set_tmp_ecdh_callback
设置ECDHE回调。
请参阅ECDHE密钥和证书不工作的服务器。
相关的,这里是基于EC的DH密码:
openssl ciphers -v 'ALL:!aNULL' | grep ECDH
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA384
ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA384
ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1
ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-RSA-AES128-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA1
ECDH-ECDSA-AES128-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA1
ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1
ECDHE-ECDSA-RC4-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=RC4(128) Mac=SHA1
ECDH-RSA-RC4-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128) Mac=SHA1
ECDH-ECDSA-RC4-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128) Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=RSA Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=3DES(168) Mac=SHA1
ECDH-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1
ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1
当我使用chrome/firefox连接到openssl s_server或我的服务器代码我得到:
140675163166384:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1396
为什么没有连接?
你用了p -521。它应该得到支持,但它可能会引起麻烦。为获得最大的互操作性,请使用p -256: ... -param_enc named_curve -name secp256k1
。
椭圆曲线齿轮在TLS 1.0及以上版本中可用。来自RFC 4492,用于传输层安全(TLS)的椭圆曲线加密(ECC)密码套件:
本文档描述了TLS支持ECC的新增内容,适用于TLS Version 1.0[2]和TLS Version 1.1[3]…
你应该改变这个:
method = TLSv1_2_server_method();
:
method = SSLv23_method();
ctx = SSL_CTX_new(method);
...
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);
这样就得到了"TLS 1.0及更高版本",并且它消除了会泄露信息的压缩。您还应该考虑其他服务器端选项,如SSL_OP_SAFARI_ECDHE_ECDSA_BUG
。
TLS 1.2是唯一提供身份验证加密的协议版本,如AES/GCM。但是你通常在密码套件列表字符串中处理这个细节。
为了完整起见,您还应该使用以下SSL_CTX_set_cipher_list
密码列表字符串:
HIGH:!aNULL:!kRSA:!RC4:!MD5
请参见浏览器发出的过时加密警告了解详细信息。
最终,你可能会遇到更多的浏览器问题。浏览器已经开始反对自签名服务器证书。若要解决此问题,请参阅如何使用证书颁发机构签署证书签名请求?
修复自签名证书后,您的服务器证书可能会因为通用名称(CN)中的服务器名称而出现问题。服务器名称必须在主题备选名称(SAN)中列出。要解决这个问题,请参见如何使用openssl创建自签名证书?
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- C++套接字客户端到 Python 服务器未创建连接
- 计算出有多少客户端可以连接到我正在使用的一些tcp服务器代码
- 在 QNX 中,如何管理服务器和客户端之间的 IPC 连接?
- QTcpSocket 在 RemoteHostClosedError 后重新连接到服务器时无法传输数据
- 如何在Qt c++中使用Secure WebSocket与服务器连接
- NAS(使用 qt/linux)- 无法建立简单的音频服务器连接测试
- C#客户端与C 服务器连接时停止,但是在与C#服务器连接时工作正常
- 如何将C++应用程序与节点.js服务器连接以获取 JSON 数据
- C++Builder-使用TIdTCPServer以编程方式创建TCP服务器连接
- 将非 IOCP 客户端与 IOCP 服务器连接
- 将 Arduino MQTT 客户端与 Node JS MQTT 服务器连接
- 提高客户端-服务器连接的稳定性
- 将web服务器连接到另一个应用程序
- Flash客户端c++服务器连接被对等方重置
- Couchbase C API-多个服务器连接
- c++服务器连接问题
- 正在连接IPv4客户端到IPv6服务器:连接拒绝
- Python客户端- c++服务器连接被拒绝错误
- 在C++中检测本地网络上的客户端-服务器连接设备