【问题标题】:C to perform HTTPS requests with opensslC 使用 openssl 执行 HTTPS 请求
【发布时间】:2020-05-26 14:27:18
【问题描述】:

我是 C 语言的新手,我正在尝试在 Linux Ubuntu 18.04 中使用 OpenSSL 执行简单的 SSL GET 请求。我在Simple C example of doing an HTTP POST and consuming the response找到了这个

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>

#define HOST "www.google.com"
#define PORT "443"

int main() {

    //
    //  Initialize the variables
    //
    BIO* bio;
    SSL* ssl;
    SSL_CTX* ctx;

    //
    //   Registers the SSL/TLS ciphers and digests.
    //
    //   Basically start the security layer.
    //
    SSL_library_init();

    //
    //  Creates a new SSL_CTX object as a framework to establish TLS/SSL
    //  or DTLS enabled connections
    //
    ctx = SSL_CTX_new(SSLv23_client_method());

    //
    //  -> Error check
    //
    if (ctx == NULL)
    {
        printf("Ctx is null\n");
    }

    //
    //   Creates a new BIO chain consisting of an SSL BIO
    //
    bio = BIO_new_ssl_connect(ctx);

    //
    //  Use the variable from the beginning of the file to create a 
    //  string that contains the URL to the site that you want to connect
    //  to while also specifying the port.
    //
    BIO_set_conn_hostname(bio, HOST ":" PORT);

    //
    //   Attempts to connect the supplied BIO
    //
    if(BIO_do_connect(bio) <= 0)
    {
        printf("Failed connection\n");
        return 1;
    }
    else
    {
        printf("Connected\n");
    }

    //
    //  The bare minimum to make a HTTP request.
    //
    char* write_buf = "GET / HTTP/1.1\r\n"
                      "Host: " HOST "\r\n"
                      "Connection: close\r\n"
                      "\r\n";

    //
    //   Attempts to write len bytes from buf to BIO
    //
    if(BIO_write(bio, write_buf, strlen(write_buf)) <= 0)
    {
        //
        //  Handle failed writes here
        //
        if(!BIO_should_retry(bio))
        {
            // Not worth implementing, but worth knowing.
        }

        //
        //  -> Let us know about the failed writes
        //
        printf("Failed write\n");
    }

    //
    //  Variables used to read the response from the server
    //
    int size;
    char buf[1024];

    //
    //  Read the response message
    //
    for(;;)
    {
        //
        //  Get chunks of the response 1023 at the time.
        //
        size = BIO_read(bio, buf, 1023);

        //
        //  If no more data, then exit the loop
        //
        if(size <= 0)
        {
            break;
        }

        //
        //  Terminate the string with a 0, to let know C when the string 
        //  ends.
        //
        buf[size] = 0;

        //
        //  ->  Print out the response
        //
        printf("%s", buf);
    }

    //
    //  Clean after ourselves
    //
    BIO_free_all(bio);
    SSL_CTX_free(ctx);

    return 0;
}

此代码运行良好,但适用于某些网站,例如ghostbin.co,连接失败...是什么原因造成的? 我使用gcc test.c -o test -lssl -lcrypto 编译代码。 我正在使用 OpenSSL 1.1.1 2018 年 9 月 11 日

【问题讨论】:

  • C 是什么时候成为脚本语言的 :(
  • @m0hithreddy 你是什么意思。你说C中没有html解析器吗?那么搜索引擎爬虫呢?我知道他们使用较低层的套接字连接,然后在整个 openssl 和 tcp 中实现
  • @user786 我的评论是针对这个stackoverflow.com/posts/62011930/…

标签: c http https openssl


【解决方案1】:

几乎总是当 OpenSSL 例程返回错误指示时,您可以并且应该从错误堆栈中获取附加信息;请参阅https://www.openssl.org/docs/faq.html#PROG8 和手册页,例如
https://www.openssl.org/docs/manmaster/man3/ERR_print_errors.html
https://www.openssl.org/docs/manmaster/man3/ERR_get_error.html
https://www.openssl.org/docs/manmaster/man3/ERR_error_string.html
https://www.openssl.org/docs/manmaster/man3/ERR_load_crypto_strings.html

但是在这种情况下,它只会告诉您服务器通过发送警报 40 中止了握手,这是 SSL/TLS 中信息量较少的警报代码之一。需要一点知识才能在 CloudFlare 上找到 ghostbin.co,它要求连接使用Server Name Indication aka SNI——本世纪许多 SSL/TLS 服务器都是如此(因为顶级 IPv4 耗尽),尤其是那些共享的服务器,如CDN 服务或共享主机。 OpenSSL API 确实允许客户端发送 SNI,但仅使用每个连接的 SSL 对象而不是 SSL_CTX,并且使用(相当陈旧且相当老旧的)BIO_ssl,SSL 对象被隐藏,因此您需要 BIO_get_ssl(bio,&amp;sslptr)然后是SSL_set_tlsext_host_name(sslptr,name)(尽管我注意到手册页的 const 错误;这实际上是一个使用 SSL_ctrl 的宏,它接受一个绝对非常量的指针)。

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 2014-10-10
    • 2021-11-22
    • 1970-01-01
    • 2014-08-25
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多