curl+personal certificate to access https site

At present, the OA management system (commonly known as the intranet) of large companies has high security requirements, and usually adopts the two-way authentication mode of https.
First of all, what is https, in short, the http protocol (get, post, etc.) implemented on top of the SSL protocol

What is two-way authentication mode? Most of the https websites facing public users belong to the one-way authentication mode, which does not need to authenticate the client and does not need to provide the client's personal certificate, such as https://www.google.com . In the two-way authentication mode, in order to verify the legitimacy of the client, the client is required to present its client certificate when accessing the server.

The following is the SSL handshake process:

①客户端的浏览器向服务器传送客户端 SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息。  
②服务器向客户端传送 SSL 协议的版本号,加密算法的种类,随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。  
③客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的 CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。  
④用户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器。  
⑤如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器。  
⑥如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的CA 是否可靠,发行CA 的公钥能否正确解开客户证书的发行 CA 的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。  
⑦服务器和客户端用相同的主密码即“通话密码”,一个对称密钥用于 SSL 协议的安全数据通讯的加解密通讯。同时在 SSL 通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。  
⑧客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。  
⑨服务器向客户端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。  
⑩SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。  

单向认证模式与双向认证模式的区别,就在于第⑤、第⑥步是否要求对客户的身份认证。单向不需要认证,双向需要认证。

Now let's introduce how to use curl to access a two-way authenticated https site.

1. Preparation

1. First of all, because you want to perform client authentication, you should have the personal certificate of the client (for the company intranet, it is usually issued to you by the IT administrator), as long as you can successfully access the two-way authentication https site, You have a personal certificate, which is hidden in the browser. All we have to do is export it from the browser. The format exported from IE browser is usually .pfx format, and the format exported from firefox is usually .p12 format. In fact, pfx=p12, they are the same thing. For curl, this format is called PKCS#12 document.
2. Convert p12 format to pem format (assuming your p12 file name is: xxx.p12):

openssl pkcs12 -in xxx.p12 -out client.pem -nokeys       #客户端个人证书的公钥  
openssl pkcs12 -in xxx.p12 -out key.pem -nocerts -nodes    #客户端个人证书的私钥  
也可以转换为公钥与私钥合二为一的文件;  
openssl pkcs12 -in xxx.p12 -out all.pem -nodes                #客户端公钥与私钥,一起存在all.pem中  

During execution, you may be required to enter the password you set when exporting the certificate. After successful execution, we have these files: client.pem - client public key, key.pem - client private key, or two-in-one all.pem.

3. Make sure that you have installed the correct version of curl (I have tossed for two days, all because there is a problem with curl-7.20.1 under fedora13, update to curl-7.21.0.tar.gz to solve the problem).

2. Execute the curl command

1. Use client.pem+key.pem
curl -k --cert client.pem --key key.pem https://www.xxxx.com
2. Use all.pem
curl -k --cert all.pem https://www.xxxx.com

Using -k, does not check the server's certificate, so you don't have to care about the export of the server's certificate.

3. Or code to access https

1. curl requests the https protocol interface in GET mode

//注意:这里的$url已经包含参数了,不带参数你自己处理哦GET很简单
function curl_get_https($url){
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在
    $tmpInfo = curl_exec($curl);     //返回api的json对象
    //关闭URL请求
    curl_close($curl);
    return $tmpInfo;    //返回json对象
}

2. curl requests the https protocol interface in POST mode

/* PHP CURL HTTPS POST */
function curl_post_https($url,$data){ // 模拟提交数据函数
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    $tmpInfo = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
        echo 'Errno'.curl_error($curl);//捕抓异常
    }
    curl_close($curl); // 关闭CURL会话
    return $tmpInfo; // 返回数据,json格式
}

3. Private certificate access https

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);   
curl_setopt($ch, CURLOPT_SSLCERT,dirname(__FILE__).'/card_test/apiclient_cert.pem'); //client.    
curl_setopt($ch, CURLOPT_SSLKEY, dirname(__FILE__).'/card_test/apiclient_key.pem');  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325812863&siteId=291194637