吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 797|回复: 2
收起左侧

[求助] 【c语言】https遇到cdn,openssl证书变成cdn。无法正确连接

[复制链接]
djwdj 发表于 2023-1-3 15:39
//  gcc -o s https.c -lssl -lcrypto

#include <stdio.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

void main(int argc, char **argv)
{
  SSL *ssl = NULL;
  SSL_CTX *ctx = NULL;
  const SSL_METHOD *client_method;
  X509 *server_cert;
  int sd,err;
  char *str,*hostname,outbuf[4096],inbuf[4096],host_header[512];
  struct hostent *host_entry;
  struct sockaddr_in server_socket_address;
  struct in_addr ip;

  /* (1) 初始化openssl库 */
  SSL_library_init();
  ERR_load_crypto_strings();
  SSL_load_error_strings();
  OpenSSL_add_all_algorithms();

  client_method = SSLv23_client_method( );
  ctx = SSL_CTX_new(client_method);
  if (!ctx) {
    fprintf (stderr, "SSL_CTX_new 失败:\n");
    ERR_print_errors_fp (stderr);
    return;
  }
  printf("(1) SSL上下文已初始化\n\n");

  /* (2) 把域名转换成ip地址 */
  hostname = argv[1];
  host_entry = gethostbyname(hostname);
  bcopy(host_entry->h_addr, &(ip.s_addr), host_entry->h_length);
  printf("(2) '%s' 具有IP地址 '%s'\n\n", hostname, inet_ntoa(ip));

  /* (3) 用tcp连接到server的443端口 */
  sd = socket(AF_INET, SOCK_STREAM, 0);
  memset(&server_socket_address, '\0', sizeof(server_socket_address));
  server_socket_address.sin_family = AF_INET;
  server_socket_address.sin_port = htons(443);
  memcpy(&(server_socket_address.sin_addr.s_addr),
      host_entry->h_addr, host_entry->h_length);
  err = connect(sd, (struct sockaddr*) &server_socket_address,
      sizeof(server_socket_address));
  if (err < 0) { perror("无法连接到服务器端口"); exit(1); }
  printf("(3) 主机的TCP连接打开 '%s', 端口 %d\n\n",
      hostname, server_socket_address.sin_port);

  /* (4) 在tcp连接上进行ssl握手 */
  ssl = SSL_new(ctx); /* 创建ssl句柄 ,之后的send,recv都在ssl句柄上进行 */
  if (!ssl) {
    fprintf (stderr, "SSL_new 失败:\n");
    ERR_print_errors_fp (stderr);
    return;
  }

  SSL_set_fd(ssl, sd); /* 把ssl句柄绑定到scoket */
  err = SSL_connect(ssl); /* 启动ssl握手 */
  printf("(4) 已创建SSL端点并完成握手\n\n");

  /* (5) 打印出协商的好的加密密文 */
  printf("(5) SSL与密码连接: %s\n\n", SSL_get_cipher(ssl));

  /* (6) 打印服务器的证书  */
  server_cert = SSL_get_peer_certificate(ssl);
  printf("(6) 已收到服务器的证书:\n\n");
  str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0);
  printf("  主题subject: %s\n", str);
  str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0);
  printf("  发行者issuer: %s\n\n", str);
  /* 这里对证书进行验证 */
  X509_free(server_cert);

  /* (7) 握手完成 --- 开始在ssl上发送http请求 */
  sprintf(host_header,"Host: %s\r\n",hostname);
  strcpy(outbuf,"GET / HTTP/1.1\r\n");
  strcat(outbuf,host_header);
//   strcat(outbuf,"Connection: close\r\n");
  strcat(outbuf,"\r\n");
  err = SSL_write(ssl, outbuf, strlen(outbuf));
  shutdown (sd, 1); /* send EOF to server */
  printf("(7) 通过加密通道发送HTTP请求:\n\n%s\n",outbuf);

  /* (8) 通过ssl句柄读取服务器响应 */
  printf ("(8) 返回了%d字节的HTTP响应:\n");
  do{
    memset(inbuf, 0, sizeof(inbuf));
    err = SSL_read(ssl, inbuf, sizeof(inbuf) - 1);
    printf ("%s",inbuf);
    inbuf[err] = '\0';
  }while(err > 0);
  /* (9) 释放连接,句柄 */
  SSL_shutdown(ssl);
  close(sd);
  SSL_free(ssl);
  SSL_CTX_free(ctx);
  printf("(9) 全部完成、清理并关闭连接\n\n");
}

这个代码能连接非cdn的https网络,连接cdn的时候,证书是cdn供应商的,通信数据不正确。
访问没有cdn的网站
./s www.baidu.com
./s www.jd.com
这个能获取网页

访问有cdn的网站
./s www.2345.com
获取的证书是alicdn,获取不到网页

小学生不会这原理,希望大佬帮忙

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ibilibili 发表于 2023-1-3 18:56
用c++搞http请求太费劲了吧。
不如试试node.js或者python。
天心阁下 发表于 2023-1-4 02:58
CDN一般都会开启SNI来解决HTTPS内容分发,你想要正确访问,需要处理SNI
参考https://www.cnblogs.com/softlee/p/16416574.html
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表