中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php實現https雙向認證的方法

發布時間:2020-08-12 09:55:13 來源:億速云 閱讀:285 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關php實現https雙向認證的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

php實現https的方法:首先修改openssl配置;然后創建CA根級證書,并將證書密碼設置長度大于或等于6位;接著創建server證書和client證書;最后配置nginx并進行php curl測試即可。

php實現https雙向認證的方法

php實現https(tls/ssl)雙向認證

通常情況下,在部署https的時候,是基于ssl單向認證的,也就是說只要客戶端認證服務器,而服務器不需要認證客戶端。

但在一些安全性較高的場景,如銀行,金融等領域,通常會要求進行客戶端認證。從而實現ssl的雙向認證。

由于nginx的ssl_client_certificate參數只能指定一個客戶端公鑰,如果增加一個客戶端進行通信就要重新配一個server。

n:1的模式是通過CA的級聯證書模式實現的,首先自己生成一套CA根級證書,再借助其生成二級證書作為client證書。

此時client私鑰簽名不僅可以通過對應的client公鑰驗證,還可通過根證書的公鑰進行驗證。

看到這里應該豁然開朗了吧,下面簡單介紹下具體怎么操作:

1 準備工作

1.1 openssl目錄準備

一般情況下openssl的配置文件都在這個目錄/etc/pki/tls,so:

mkdir /etc/pki/ca_linvo
cd /etc/pki/ca_linvo
mkdir root server client newcerts
echo 01 > serial
echo 01 > crlnumber
touch index.txt

1.2 openssl配置準備

修改openssl配置

vi /etc/pki/tls/openssl.cnf

找到這句注釋掉,替換為下面那句

#default_ca      = CA_default
default_ca      = CA_linvo

把[ CA_default ]整個部分拷貝一份,改成上面的名字[ CA_linvo ]

修改里面的如下參數:

dir = /etc/pki/ca_linvo
certificate = $dir/root/ca.crt
private_key = $dir/root/ca.key

保存退出

2 創建CA根級證書

生成key:openssl genrsa -out /etc/pki/ca_linvo/root/ca.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.csr
生成crt:openssl x509 -req -days 3650 -in /etc/pki/ca_linvo/root/ca.csr -signkey /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.crt
生成crl:openssl ca -gencrl -out /etc/pki/ca_linvo/root/ca.crl -crldays 7

生成的根級證書文件都在/etc/pki/ca_linvo/root/目錄下

注意:創建證書時,建議證書密碼設置長度>=6位,因為Java的keytool工具貌似對它有要求。

3 創建server證書

生成key:openssl genrsa -out /etc/pki/ca_linvo/server/server.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/server/server.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/server/server.crt -days 3650

說明:

1、這里生成的crt是剛才ca根級證書下的級聯證書,其實server證書主要用于配置正常單向的https,所以不使用級聯模式也可以:

openssl rsa -in /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.key
openssl x509 -req -in /etc/pki/ca_linvo/server/server.csr -signkey /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.crt -days 3650

2、-days 參數可根據需要設置證書的有效期,例如默認365天

4 創建client證書

生成key:openssl genrsa -des3 -out /etc/pki/ca_linvo/client/client.key 1024
生成csr:openssl req -new -key /etc/pki/ca_linvo/client/client.key -out /etc/pki/ca_linvo/client/client.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/client/client.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/client/client.crt -days 3650

說明:

1、這里就必須使用級聯證書,并且可以重復該步驟,創建多套client證書

2、生成crt時可能會遇到如下報錯:

openssl TXT_DB error number 2 failed to update database

可參照這里進行操作。

我使用的是方法一,即將index.txt.attr中unique_subject = no

5 配置nginx

這里只列出server段的關鍵部分:

ssl_certificate  /etc/pki/ca_linvo/server/server.crt;#server公鑰
ssl_certificate_key  /etc/pki/ca_linvo/server/server.key;#server私鑰
ssl_client_certificate   /etc/pki/ca_linvo/root/ca.crt;#根級證書公鑰,用于驗證各個二級client
ssl_verify_client on;

重啟Nginx

6 測試

6.1 瀏覽器測試

由于是雙向認證,直接通過瀏覽器訪問https地址是被告知400 Bad Request(No required SSL certificate was sent)的,需要在本機安裝client證書。

windows上安裝的證書需要pfx格式,也叫p12格式,生成方式如下:

openssl pkcs12 -export -inkey /etc/pki/ca_linvo/client/client.key -in /etc/pki/ca_linvo/client/client.crt -out /etc/pki/ca_linvo/client/client.pfx

然后考到windows中雙擊即可進行安裝,安裝時會提示輸入生成證書時設置的密碼。

安裝成功后,重啟瀏覽器輸入網址訪問,瀏覽器可能會提示你選擇證書,選擇剛才安裝的那個證書即可。

此時有些瀏覽器會提示用戶該證書不受信任,地址不安全之類,這是因為我們的server證書是我們自己頒發的,而非真正的權威CA機構頒布(通常很貴哦~),忽略它既可。

6.2 php curl測試

這里只列出關鍵的需要設置的curl參數:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何證書,不是CA機構頒布的也沒關系  
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 檢查證書中是否設置域名,如果不想驗證也可設為0  
curl_setopt($ch, CURLOPT_VERBOSE, '1'); //debug模式,方便出錯調試  
curl_setopt($ch, CURLOPT_SSLCERT, CLIENT_CRT); //client.crt文件路徑,這里我用常量代替  
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, CRT_PWD); //client證書密碼  
curl_setopt($ch, CURLOPT_SSLKEY, CLIENT_KEY); //client.key文件路徑  
 
CURLOPT_TIMEOUT:超時時間
CURLOPT_RETURNTRANSFER:是否要求返回數據
CURLOPT_SSL_VERIFYPEER:是否檢測服務器的證書是否由正規瀏覽器認證過的授權CA頒發的
CURLOPT_SSL_VERIFYHOST:是否檢測服務器的域名與證書上的是否一致
CURLOPT_SSLCERTTYPE:證書類型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLCERT:證書存放路徑
CURLOPT_SSLCERTPASSWD:證書密碼,沒有可以留空
CURLOPT_SSLKEYTYPE:私鑰類型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLKEY:私鑰存放路徑
 
 
function curl_post_ssl($url, $vars, $second=30,$aHeader=array())
{
    $ch = curl_init();
    //curl_setopt($ch,CURLOPT_VERBOSE,'1');
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT,'/data/cert/php.pem');
    curl_setopt($ch,CURLOPT_SSLCERTPASSWD,'1234');
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY,'/data/cert/php_private.pem');
 
    if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
    }
 
    curl_setopt($ch,CURLOPT_POST, 1);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
    $data = curl_exec($ch);
    curl_close($ch);
    if($data)
            return $data;
    else   
            return false;
}

驗證失敗,nginx的錯誤日志中,會有如下信息

2017/06/05 17:45:07 [crit] 16084#0: *27458991 SSL_do_handshake() failed (SSL: error:04067084:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data too large for modulus e
rror:1408807A:SSL routines:ssl3_get_cert_verify:bad rsa signature) while SSL handshaking, client: 116.255.208.194, server: 0.0.0.0:443

6.3 php soap測試

首先需要構建client的pem格式證書,通過openssl命令也可以,不過因為我們已經有了crt和key,所以手動合并也很簡單:

新建一個文件,把crt中-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----之間的base64內容(包括這兩個分割線)拷貝進去,然后把key中-----BEGIN RSA PRIVATE KEY-----和-----END RSA PRIVATE KEY-----之間的內容也復制進去,然后保存為client.pem即可。

其實更省事的話可以如下命令,直接合并兩個文件:

cat /etc/pki/ca_linvo/client/client.crt /etc/pki/ca_linvo/client/client.key > /etc/pki/ca_linvo/client/client.pem

有了pem文件,下面可以使用php內置的SoapClient進行調用,構造函數需要設置第二個參數:

$header = array(          
    'local_cert' => CLIENT_PEM, //client.pem文件路徑  
    'passphrase' => CRT_PWD //client證書密碼  
    );  
$client = new SoapClient(FILE_WSDL, $header); //FILE_WSDL為要訪問的https地址

上一篇博客里最后說到local_cert設置成遠程路徑的話會報錯,好像是因為第一次獲取wsdl時并沒有使用client證書的原因,需要將wsdl保持成本地文件進行調用;

但是這次測試卻沒問題,不用另存為本地文件,直接遠程獲取即可。

本來認為是之前的證書有問題,但是使用之前的那套證書依然可以,很是詭異~~~~~

關于php實現https雙向認證的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

舞阳县| 吴忠市| 合肥市| 镇原县| 台东市| 务川| 韩城市| 武功县| 彭州市| 新郑市| 清水河县| 彭阳县| 耒阳市| 井陉县| 喜德县| 枞阳县| 怀集县| 珲春市| 新平| 巴彦县| 上林县| 夹江县| 子洲县| 昔阳县| 孙吴县| 奉贤区| 密山市| 岢岚县| 昌图县| 抚顺市| 通化县| 石河子市| 西吉县| 永昌县| 堆龙德庆县| 克拉玛依市| 商南县| 抚州市| 凤翔县| 嵊州市| 鹤峰县|