这段时间在做本地终端链接服务器的工作,在此记录下,以免将来忘了。
首先有一个已经搭建好的nginx服务器,并且能够实现单向认证。
然后现在服务器端生成证书请求文件。
1.用openssl创建私钥
openssl genrsa -out server.key
2.用私钥创建证书请求文件
openssl req -new -key server.key -out server.csr
CA签发证书:
CA是专门签发证书的权威机构,处于证书的最顶端。自签是用自己的私钥给证书签名,CA签发则是用CA的私钥给自己的证书签名来保证证书的可靠性。因为是要实现单向认证,所以就要有CA进行认证。因为CA认证机构是要花钱的,因此自己创建CA。
1.生成CA私钥和证书
openssl req -new -x509 -keyout ca.key -out ca.crt
2.生成CA签名证书
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -config openssl.cnf
这里我用openssl.cnf来自定义生成ca.crt的路径。openssl.cnf默认的存放路径在/etc/pki/tls
在openssl.cnf中只修改了一行
#dir = /etc/pki/CA //默认地址
dir = /home/pki/ServerCert
certs = $dir/certs
创建完成后,本地需要的文件是ca.crt,nginx服务中需要的是server.crt。
在nginx中配置证书如下:
server {
listen 443 ssl;
server_name localhost;
ssl on;
ssl_certificate /etc/nginx/pki/server.crt;
ssl_certificate_key /etc/nginx/pki/server.key;
ssl_protocols TLSv1.2;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
...
...
}
下一步,在本地尝试用curl工具进行链接测试。
curl -v --cacert ca.crt https://198.168.1.145
得到服务器的登录页面的html。
注意,不要在curl后加 -k,-k是忽略了证书的正确与否,不能保证是否实现了认证。
最后用c代码实现这个链接过程。
#include
#include
#include
#include "lic.h"
#include
#define FILENAME "sr.dat"
#define URL "https://192.168.1.145"
size_t write_data(void* buffer,size_t size,size_t nmemb,void *stream)
{
FILE *fptr = (FILE*)stream;
fwrite(buffer,size,nmemb,fptr);
return size*nmemb;
}
int download_license(char *UniqueID, char *OderNum)
{
CURL *curl;
CURLcode res;
FILE * fptr;
char post_parameter[4096]; //传入的参数
struct curl_slist *http_header = NULL; //定义参数头
struct curl_slist *headers = NULL;
char *pCaPath = "/home/pki/ca.crt";
//char *UniqueID = arg[1];
//char *OderNum = arg[2];
if (! UniqueID)
{
fprintf(stderr,"Please enter unquieID!\n"); //没有输入UnquieID
exit(0);
}
else
{
if (! OderNum)
{
fprintf(stderr,"Please enter oder num!\n"); //没有输入Oder num
exit(0);
}
else
{
strcpy(post_parameter,"licenseID=%22"); //拼接输入的参数
strcat(post_parameter, UniqueID);
strcat(post_parameter, "%22&OderNumber=%22");
strcat(post_parameter, OderNum);
strcat(post_parameter, "%22");
}
}
if ((fptr = fopen(FILENAME,"w")) == NULL)
{
fprintf(stderr,"fopen file error:%s\n",FILENAME); //文件打开错误
return -1;
}
headers = curl_slist_append(headers, "Host: 192.168.65.128");
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0");
headers = curl_slist_append(headers, "Accept: application/json, text/javascript, */*; q=0.01");
headers = curl_slist_append(headers, "Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate");
headers = curl_slist_append(headers, "X-Requested-With: XMLHttpRequest");
headers = curl_slist_append(headers, "Cookie: lastTimeLines=0; cipher_session=1; cipher_key=1; down=1");
curl = curl_easy_init();
if (!curl)
{
fprintf(stderr,"curl init failed\n");
return -1;
}
//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);//openssl编译时使用curl官网或者firefox导出的第三方根证书文件
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
curl_easy_setopt(curl, CURLOPT_URL, URL); //url地址
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,post_parameter); //post参数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,write_data); //对返回的数据进行操作的函数地址
curl_easy_setopt(curl, CURLOPT_WRITEDATA,fptr); //这是write_data的第四个参数值
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
switch(res)
{
case CURLE_UNSUPPORTED_PROTOCOL:
fprintf(stderr,"不支持的协议,由URL的头部指定\n");
case CURLE_COULDNT_CONNECT:
fprintf(stderr,"不能连接到remote主机或者代理\n");
case CURLE_HTTP_RETURNED_ERROR:
fprintf(stderr,"http返回错误\n");
case CURLE_READ_ERROR:
fprintf(stderr,"读本地文件错误\n");
default:
fprintf(stderr,"返回值:%d\n",res);
}
return -1;
}
close(fptr);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}