【发布时间】:2015-08-07 09:53:26
【问题描述】:
生成的密钥
openssl ecparam -param_enc named_curve -name secp521r1 -genkey -outform PEM -out key.pem
生成的证书
openssl req -x509 -new -key key.pem -keyform PEM -out ca.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>\n\n";
err = SSL_accept(ssl);
if ( err <= 0 ) { /* do SSL-protocol accept */
printf("%d\n",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 certificate\n");
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:%d\n",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
不是ECDHE!为什么?
当我使用 chrome/firefox 连接到 openssl s_server 或我的服务器代码时,我得到:
140675163166384:error:1408A0C1:SSL 例程:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1396:
为什么完全没有连接?
【问题讨论】:
-
我正在使用 OpenSSL 1.0.2a 2015 年 3 月 19 日我通过使用 cout 在代码开头打印它来检查这一点