使用curl+openssl实现单项身份验证

1、首先编译OpenSSL,我是用的是gmssl;

./config --prefix=/home/fanxiangqiang/src/GmSSL-master/build

使用curl+openssl实现单项身份验证

 2、编译curl,这里需要指定Gmssl的安装路径;

./configure   --with-http_ssl_module --with-nghttp2 --prefix=/home/fanxiangqiang/src/curl-7.76.1/build  --with-ssl=/home/fanxiangqiang/src/GmSSL-master/build 

编译完成就OK。

3、测试demo,单向验证链接测试网页 www.example.com;先登录上这个网站,导出DER格式证书

使用curl+openssl实现单项身份验证

 4、测试demo

/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/
/* <DESC>
 * Simple HTTPS GET
 * </DESC>
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "stddef.h"
#include <time.h>
#include "curl.h"
#include "easy.h"
#include <string.h>
#include "curl.h"
 #define POSTURL "https://www.example.com"
#define oneway_certification 0
// size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
// { //一次返回可能对应多次调用,此处用于拼接完整版的返回信息
//     size_t realsize = size * nmemb;
//     /*   struct MemoryStruct *mem = (struct MemoryStruct *)data;
//      mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
//      if (mem->memory)
//      {
//           memcpy(&(mem->memory[mem->size]), ptr, realsize);
//           mem->size += realsize;
//           mem->memory[mem->size] = 0;
//      }*/
//       printf("recive data \r\n%s\r\n",ptr);
//      return realsize;
// }

// size_t WriteMemoryCallback(void *buffer, size_t size, size_t nmemb, FILE *file) {
//   //  size_t r_size = fwrite(buffer, size, nmemb, file);
//    // return r_size;
//    printf("XXXXXXXXXXXXXXXXXXXXX");
// }
char path[] = "save_file.txt";


int main(void)
{
  CURL *curl;
  CURLcode res;
 
  curl_global_init(CURL_GLOBAL_DEFAULT);
  FILE *file = fopen(path,"w");
  curl = curl_easy_init();
  if(curl) {
     curl_easy_setopt(curl, CURLOPT_URL, POSTURL);  //设置post address
     curl_easy_setopt(curl, CURLOPT_POST,0);           ///使用post

     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 13L);          ///设置超时
     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);   //重连超时

     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);        //启用时会汇报所有的信息
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); 

     if(!oneway_certification)
{
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); // 验证服务器证书有效性
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);// 检验证书中的主机名和你访问的主机名一致
    curl_easy_setopt(curl, CURLOPT_CAINFO, "CA.der"); // 指定 CA 证书路径
}
else
{
    // 不验证服务器证书
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
}

     //curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);  //得到请求结果后的回调函数

        struct curl_slist *pList = NULL;

     pList = curl_slist_append(pList, "User-Agent: lanyou");
     pList = curl_slist_append(pList, "Accept:application/json");
      pList = curl_slist_append(pList, "Content-Type: application/json");
        pList = curl_slist_append(pList, "charset:utf-8");
     //  pList = curl_slist_append(pList, "Expect:");
     pList = curl_slist_append(pList, "Connection: close");
     char temp[64] = {0};
    //  char *test_data = "test";
    //  sprintf(temp, "Content-Length: %d\r\n", strlen(test_data)); // data length
    //  pList = curl_slist_append(pList, temp);
    //  pList = curl_slist_append(pList, test_data);
    //  pList = curl_slist_append(pList, "\r\n");
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pList);
#ifdef SKIP_PEER_VERIFICATION
    /*
     * If you want to connect to a site who isn't using a certificate that is
     * signed by one of the certs in the CA bundle you have, you can skip the
     * verification of the server's certificate. This makes the connection
     * A LOT LESS SECURE.
     *
     * If you have a CA cert for the server stored someplace else than in the
     * default bundle, then the CURLOPT_CAPATH option might come handy for
     * you.
     */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
 
#ifdef SKIP_HOSTNAME_VERIFICATION
    /*
     * If the site you're connecting to uses a different host name that what
     * they have mentioned in their server certificate's commonName (or
     * subjectAltName) fields, libcurl will refuse to connect. You can skip
     * this check, but this will make the connection less secure.
     */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
 
    /* Perform the request, res will get the return code */
    
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
     curl_slist_free_all(pList); 
      long res_code = -1;
      res = -1;
     res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code);
    
      if (res == CURLE_OK)
       {
            if (res_code == 200 || res_code == 201)
            {
               
                printf("result code is %d\r\n",res_code);
            }
       }
    curl_easy_cleanup(curl);
    curl_global_cleanup(); 
  }
 printf("result code is %d\r\n",res);

  return 0;
}

运行结果

*   Trying 93.184.216.34:443...
*   Trying 2606:2800:220:1:248:1893:25c8:1946:443...
* Immediate connect fail for 2606:2800:220:1:248:1893:25c8:1946: Network is unreachable
* Connected to www.example.com (93.184.216.34) port 443 (#0)
* ALPN, offering http/1.1
* error setting certificate verify locations, continuing anyway:
*  CAfile: CA.der
*  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=US; ST=California; L=Los Angeles; O=Internet Corporation for Assigned Names and Numbers; CN=www.example.org
*  start date: Nov 24 00:00:00 2020 GMT
*  expire date: Dec 25 23:59:59 2021 GMT
*  subjectAltName: host "www.example.com" matched cert's "www.example.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
> GET / HTTP/1.1
Host: www.example.com
User-Agent: lanyou
Accept:application/json
Content-Type: application/json
charset:utf-8
Connection: close

* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Age: 580557
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Tue, 13 Jul 2021 01:16:51 GMT
< Etag: "3147526947"
< Expires: Tue, 20 Jul 2021 01:16:51 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/5798)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
< Connection: close
< 
* Closing connection 0
result code is 200
result code is 0

下载到的网页: 

<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

使用curl+openssl实现单项身份验证

 

上一篇:关于本博客和博主


下一篇:OpenVPN 搭建部署--实现外网访问内网