zoukankan      html  css  js  c++  java
  • libcurl+openssl实现https爬虫

    https图解:

    1、客户端向服务端发送SSL协议版本号、加密算法种类、随机数等信息。

    2、服务端给客户端返回SSL协议版本号、加密算法种类、随机数等信息,同时也返回服务器端的证书,即公钥证书

    3、客户端使用服务端返回的信息验证服务器的合法性,包括:

    证书是否过期

    发型服务器证书的CA是否可靠

    返回的公钥是否能正确解开返回证书中的数字签名

    服务器证书上的域名是否和服务器的实际域名相匹配

    验证通过后,将继续进行通信,否则,终止通信

    4、客户端向服务端发送自己所能支持的对称加密方案,供服务器端进行选择

    5、服务器端在客户端提供的加密方案中选择加密程度最高的加密方式。

    6、服务器将选择好的加密方案通过明文方式返回给客户端

    7、客户端接收到服务端返回的加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密的密钥,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器

    8、服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获取对称加密密钥。 在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中信息的安全。

    libcurl库:

    libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。文档地址https://curl.haxx.se/libcurl/c/libcurl.html

    libcurl和curl命令的区别:

    相同点

    curl和libcurl都可以利用多种多样的协议来传输文件,包括HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE等。

    都支持支持SSL证书,HTTP POST, HTTP PUT,FTP上传,基于表单的HTTP上传,代理(proxies)、cookies、用户名/密码认证(Basic, Digest, NTLM等)、下载文件断点续传,上载文件断点续传(file transfer resume),http代理服务器管道(proxy tunneling)等

    不同点

    curl是命令行工具,可以通过shell或脚本来运行curl。curl底层所使用的库是libcurl。
    libcurl是一个库,通常与别的程序绑定在一起使用,如命令行工具curl就是封装了libcurl库。所以我们也可以在你自己的程序或项目中使用libcurl以获得类似CURL的强大功能。

    实例:

    1获取

    #include <stdio.h>
    #include <curl/curl.h>
    #include <stdlib.h>
    int main(int argc, char *argv[])
    {
        CURL *curl;             //定义CURL类型的指针
        CURLcode res;           //定义CURLcode类型的变量,保存返回状态码
        if(argc!=2)
        {
            printf("Usage : file <url>;
    ");
            exit(1);
        }
     
        curl = curl_easy_init();        //初始化一个CURL类型的指针
        if(curl!=NULL)
        {
            //设置curl选项. 其中CURLOPT_URL是让用户指 定url. argv[1]中存放的命令行传进来的网址
            curl_easy_setopt(curl, CURLOPT_URL, argv[1]);        
            //调用curl_easy_perform 执行我们的设置.并进行相关的操作. 在这 里只在屏幕上显示出来.
            res = curl_easy_perform(curl);
            //清除curl操作.
            curl_easy_cleanup(curl);
        }
        return 0;
    }
    View Code

    编译:

    gcc  http1.c  -o http1 lcurl

    执行:

    ./http1 www.baidu.com

    本例只引入了libcurl的函数库,

    调用curl_global_init()初始化libcurl
    调用curl_easy_init()函数得到 easy interface型指针
    调用curl_easy_setopt()设置传输选项
    根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务
    调用curl_easy_perform()函数完成传输任务
    调用curl_easy_cleanup()释放内存
    在整个过程中设置curl_easy_setopt()参数是最关键的,几乎所有的libcurl程序都要使用它。

    实例2:进行ssl验证

    /* <DESC>
     * 一个简单的https get ,输出网页并验证  
     * </DESC>
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <curl/curl.h>
    
    int main(int argc, char *argv[])
    {
        CURL *curl;             //定义CURL类型的指针
        CURLcode res;           //定义CURLcode类型的变量,保存返回状态码
    /*
        if(argc!=2)
        {
            printf("Usage : file <url>;
    ");
            exit(1);
        }
    */
        //初始化SSL and Win32运行环境
        curl_global_init(CURL_GLOBAL_DEFAULT);
    
        curl = curl_easy_init();        //初始化一个CURL类型的指针
        if(curl!=NULL)
        {
            //设置curl选项. 其中CURLOPT_URL是让用户指 定url. argv[1]中存放的命令行传进来的网址
            curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com");
            //curl_easy_setopt(curl, CURLOPT_URL, argv[1]);        
    
            //用第三方机构颁发的CA证书解密服务器端返回的证书并验证合法性,默认1L开启检查,0L忽略检查
            curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L);
            //验证返回的证书是否与请求的域名相同,避免被篡改证书文件,默认值2L,0L忽略检查
            curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,2L);
    
            //curl_easy_setopt(curl,CURLOPT_CAPATH,ca_path);//ca证书路径
            curl_easy_setopt(curl,CURLOPT_CAINFO,"cacert.pem");//curl官网下载的根证书
    
    
            //设置curl选项,其中CURLOPT_VERBOSE是显示执行过程中的调试信息 输出到控制台
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
            //不显示进度,如果设置为0L,则显示处理的进度条
            curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
    
            //调用curl_easy_perform 执行我们的设置.并进行相关的操作. 在这 里只在屏幕上显示出来.
            res = curl_easy_perform(curl);
    
            //检查错误信息输出到控制台
            if(res!=CURLE_OK){
                fprintf(stderr,"curl_easy_perfrom() failed:%s
    ",curl_easy_strerror(res));
            }
            //清除curl操作.
            curl_easy_cleanup(curl);
        }
        curl_global_cleanup();
        return 0;
    }
    View Code

    (1)到 curl 官网下载证书

      curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem
    (2)在你的程序中设置证书的路径

    // 不检查证书
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    // SSL CA证书
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);                    // 验证服务器证书有效性
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);                    // 检验证书中的主机名和你访问的主机名是否一致
    curl_easy_setopt(curl, CURLOPT_CAPATH, "./lib/");                    // 设置证书路径
    //curl_easy_setopt(curl, CURLOPT_CAINFO, "./lib/cacert.pem");            // 具体的 CA 证书,和上一行效果一样,选用一个即可

    (1)使用 PATH 或 INFO 设置路径前要用curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);开启验证证书功能
    (2)使用curl_easy_setopt(curl, CURLOPT_CAPATH, "./lib/");设置证书路径
    或使用curl_easy_setopt(curl, CURLOPT_CAINFO, "./lib/cacert.pem");设置具体的 CA 证书
  • 相关阅读:
    Ubuntu12.04 亮度调节和保存
    算法
    Python一些常见问题的解决方法
    数据结构
    C# 运行时编译代码并执行 【转】
    C# 动态添加属性 非原创 有修改
    30天学通Visual C++项目案例开发 下載
    .NET常用Request获取信息
    获取一个目录下所有的文件,包括子目录的
    C++入门到精通_全集下载
  • 原文地址:https://www.cnblogs.com/xfvipp/p/12837332.html
Copyright © 2011-2022 走看看