C中的OpenSSL-例程:ssl3_get_record:尝试使用TLS1_2连接到服务器时版本号错误

Posted

技术标签:

【中文标题】C中的OpenSSL-例程:ssl3_get_record:尝试使用TLS1_2连接到服务器时版本号错误【英文标题】:OpenSSL in C - routines:ssl3_get_record:wrong version number when trying to connect to server using TLS1_2 【发布时间】:2022-01-14 13:39:11 【问题描述】:

我正在尝试制作一个可以向 C 中的服务器发送请求的“curl”客户端。 我已经创建了一个 TCP 套接字(使用大学的幻灯片,经过测试):

int connect_to_host(char * hostname, int port) 
  // AF_INET: create socket that uses IPv4; SOCK_STREAM: type of sequenced, reliable
  // 2-way connection-based byte streams ~ TCP (as opposed to datagrams ~ UDP)
  int socket_fd;
  struct sockaddr_in server_addr;
  struct hostent * hp;
  
  if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    return -1; // remember to broadcast error, saved in errno (extern int errno)
  
  
  // geting address (contained in struct hostent) from DNS
  if ((hp = gethostbyname(hostname)) == NULL) 
    return -2; // can't find hostname from DNS
  
  // per documentation, must zero out bytes in the 'server' socket address before filling values
  bzero((char *)&server_addr, sizeof(server_addr));
  // filling necessary values of the 'server' socket address
  server_addr.sin_family = AF_INET; // using IPv4
  server_addr.sin_port = htons(port); // assign port value, remember to change int (host order byte)
                                      // to network order byte. htons = host-to-network-short (short int)
  bcopy((char *)hp->h_addr_list[0], (char *)&server_addr.sin_addr.s_addr, hp->h_length); // IP address, got from DNS
  
  if (connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 
    return -1; // error, as above
  
  return socket_fd;

并创建了一个 TLS 版本灵活的 SSL/TLS 上下文:

SSL_CTX * init_CTX() 
  SSL_METHOD * method;
  SSL_CTX * ctx;
  OpenSSL_add_all_algorithms(); // Load cryptos, et.al.
  SSL_load_error_strings(); // Bring in and register error messages
  method = TLS_client_method(); // create new client-method instance
  if ((ctx = SSL_CTX_new(method)) == NULL) ; // create new context
    return NULL;
  
  return ctx;

我的下一步是创建一个 SSL 连接状态并将其与上面 TCP 函数 (connect_to_host()) 返回的文件描述符“绑定”。然后我会尝试做 SSL_connect()

if (*tls_mode == 1) 
  ctx = init_CTX();
  ssl = SSL_new(ctx); // create new SSL connection state
  SSL_set_fd(ssl, clientfd); // bind socket descriptor to ssl state
  if (SSL_connect(ssl) == -1) 
    printf("SSL connection failed\n");
    ERR_print_errors_fp(stderr);
    return -1;
  
  printf("debug tls: connect\n");
  if (show_cert) SSL_show_certs(ssl);

此时我收到标题中的错误。我已经检查了 *** 和位置,但我没有看到使用 C 和 OpenSSL 库的问题。如果有人能给我提示,我将不胜感激。

【问题讨论】:

在尝试与一开始不使用 SSL/TLS 的服务器建立 SSL/TLS 连接时,通常会出现这种错误。那么,您尝试连接的服务器是什么,它甚至在给定端口上使用 SSL/TLS 吗? 我试图连接到 https://www.google.com。当我尝试使用 http://www.google.com(http 不安全)进行 HTTP 时,一切顺利。所以我猜想创建套接字部分工作正常,并且认为 SSL/TLS 可能是问题所在。 哦,谢谢。说完我检查了我的端口变量,发现端口号是错误的。现在问题已解决。感谢您的帮助,对此深表歉意。 【参考方案1】:

因此,对于稍后检查此问题的任何人,我的端口号出错,并连接到端口 80 而不是 443,从而导致错误。

【讨论】:

以上是关于C中的OpenSSL-例程:ssl3_get_record:尝试使用TLS1_2连接到服务器时版本号错误的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL RSA解密随机失败C / C ++

Poco+OpenSSL,错误:1416F086:SSL 例程:tls_process_server_certificate:证书验证失败

openssl_verify 和“错误:0906D06C:PEM 例程:PEM_read_bio:没有起始行”

Firebase PHP JWT“OpenSSL 无法验证数据:错误:0906D06C:PEM 例程:PEM_read_bio:no start line”

PayPal IPN OPENSSL 错误:14077410:SSL 例程:SSL23_GET_SERVER_HELLO:sslv3 警报握手失败

从私钥生成CSR的OpenSSL错误