HTTPS认证四:使用开源libcurl进行SSL双向认证

官网:https://curl.haxx.se/libcurl/c/libcurl.html

libcurl参数说明:

CURLOPT_SSLCERTTYPE:证书的格式,支持PEM, DER格式
CURLOPT_SSLCERT:客户端证书的名字,加密传输下默认格式是P12,其它方式下是PEM,使用时候用./filename避免混淆,当使用client证书的时候,很大可能需要使用private key
CURLOPT_SSLKEY: 这个是privatekey的文件名,默认格式是PEM,可以通过 CURLOPT_SSLKEYTYPE修改
CURLOPT_KEYPASSWD: 使用private.key时候需要密码,载入证书不会用到密码,但是载入private.key时候需要
CURLOPT_CAINFO: 根证书,用来验证对端证书的有效性,一般时颁发机构(CA)颁发的
CURLOPT_SSL_VERIFYPEER: 决定是否验证对方证书的有效性,当进行TLS或者SSL连接时,服务器发送证书表明他的身份,CURL会验证证书是否真实(,这种信任基于数字签名链,植根于您提供的证书颁发机构(CA)证书

1、准备文件

 

根证书

ca.crt

cacrt.pem

根证书签发的服务端证书

server.crt

 

服务端私钥

server.key

 

根证书签发的客户端证书

client.crt

clientcrt.pem

客户端私钥

client.key

clientkey.pem

 cacrt.pem :为了验证服务器的证书,因为服务器证书时通过根证书签发的

 clientcrt.pem, clientkey.pem :客户端证书,双向认证发给服务器进行认证

头文件记libcurl库文件(参考github libcurl开源)

2、simplc.c文件

#include <stdio.h>
#include "include/curl/curl.h"
int main(void)
{
  CURL *curl;
  CURLcode res;
  FILE *headerfile;
  const char *pPassphrase = NULL;    //password for private key

  static const char *pCertFile = "./clientcrt.pem"; //client certificate
  static const char *pCACertFile = "cacrt.pem"; //CA root certificat
  static const char *pHeaderFile = "dumpit";

  const char *pKeyName;
  const char *pKeyType;

  const char *pEngine;

  pKeyName  = "clientkey.pem";        // private.key
  pKeyType  = "PEM";
  pEngine   = NULL;

  headerfile = fopen(pHeaderFile, "wb");

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();
   if(curl) {
    /* what call to write: */
    curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://192.168.31.14:8124");
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile);

    do { /* dummy loop, just to break out from */
      if(pEngine) {
        /* use crypto engine */
        if(curl_easy_setopt(curl, CURLOPT_SSLENGINE, pEngine) != CURLE_OK) {
          /* load the crypto engine */
          fprintf(stderr, "can't set crypto engine\n");
           break;
        }
        if(curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) {
          /* set the crypto engine as default */
          /* only needed for the first time you load
 *              a engine in a curl object... */
          fprintf(stderr, "can't set crypto engine as default\n");
          break;
        }
      }
      /* cert is stored PEM coded in file... */
      /* since PEM is default, we needn't set it for PEM */
      curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");

      /* set the cert for client authentication */
      curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile);

      /* sorry, for engine we must set the passphrase
 *          (if the key has one...) */
      if(pPassphrase)
        curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPassphrase);

      /* if we use a key stored in a crypto engine,
 *          we must set the key type to "ENG" */
      curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, pKeyType);

      /* set the private key (file or ID in engine) */
      curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName);

      /* set the file with the certs vaildating the server */
      curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile);

      /* disconnect if we can't validate server's cert */
      curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);

      /* 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));

      /* we are done... */
    } while(0);
    /* always cleanup */
    curl_easy_cleanup(curl);
  }

  curl_global_cleanup();

  return 0;
}

 

 Makefile

TARGET = simplessl

#Which object files that the executable consists of
OBJS= simplessl.o
# What compiler to use
CC = gcc

# Compiler flags, -g for debug, -c to make an object file
CFLAGS = -c -g
# This should point to a directory that holds libcurl, if it isn't
# in the system's standard lib dir
# We also set a -L to include the directory where we have the openssl
# libraries
LDFLAGS = -L./lib/libs -L/usr/local/ssl/lib

# We need -lcurl for the curl stuff
# We need -lsocket and -lnsl when on Solaris
# We need -lssl and -lcrypto when using libcurl with SSL support
# We need -lpthread for the pthread example
LIBS = -lcurl #-lsocket -lnsl -lssl -lcrypto

# Link the target with all objects and libraries
$(TARGET) : $(OBJS)
        $(CC)  -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)

# Compile the source files into object files
simplessl.o : simplessl.c
        $(CC) $(CFLAGS) $<

编译后执行可以看到结果:

请到我的下载资源中找源代码 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想在 libcurl使用 gmSSL 进行双向认证,可以按照以下步骤进行操作: 1. 生成服务器证书和私钥。可以使用 OpenSSL 工具生成证书和私钥。例如: ``` openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt ``` 2. 生成客户端证书和私钥。可以使用 OpenSSL 工具生成证书和私钥。例如: ``` openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr openssl x509 -req -days 365 -in client.csr -signkey client.key -out client.crt ``` 3. 将服务器证书和私钥放到服务器端,将客户端证书和私钥放到客户端。 4. 在服务器端,启动一个 HTTPS 服务器,并加载服务器证书和私钥。可以使用 OpenSSL 或其他 HTTP 服务器软件来实现。在这里,我们假设你已经启动了一个名为 `example.com` 的 HTTPS 服务器,并将服务器证书和私钥保存在 `server.crt` 和 `server.key` 文件中。 5. 在客户端,使用 libcurl 发起 HTTPS 请求,并加载客户端证书和私钥。可以使用以下代码来实现: ``` #include <curl/curl.h> #include <openssl/gmssl.h> int main() { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "ECDHE-ECDSA-AES128-GCM-SHA256"); curl_easy_setopt(curl, CURLOPT_CAINFO, "ca-bundle.crt"); curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.crt"); curl_easy_setopt(curl, CURLOPT_SSLKEY, "client.key"); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; } ``` 在上面的示例代码中,我们使用了 `CURLOPT_SSLCERT` 和 `CURLOPT_SSLKEY` 选项来加载客户端证书和私钥。需要注意的是,客户端证书需要是 PEM 格式,并且需要包含完整的证书链。 同时,我们还设置了 `CURLOPT_CAINFO` 选项来加载根证书。如果根证书不在系统的默认位置,需要将其保存为 PEM 格式,并指定其路径。 需要注意的是,双向认证需要在服务器端和客户端都进行配置,才能实现双向认证的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值