1.明確https域名,如:tomcat.loc,生成證書時(shí)使用
2.創(chuàng)建證書目錄
//進(jìn)入tmp目錄
cd /home/guangzheng/tmp
//創(chuàng)建ca目錄,存放證書相關(guān)文件
mkdir ca
//進(jìn)入ca
cd ca
3.制作根證書
? ? 3.1 創(chuàng)建根證書密鑰文件(自己做CA) root.key
openssl genrsa -des3 -out root.key 2048
//輸出內(nèi)容為:
guangzheng@ljlj:~/tmp/ca$ openssl genrsa -des3 -out root.key 2048
Generating RSA private key, 2048 bit long modulus
....+++
.......................+++
e is 65537 (0x10001)
Enter pass phrase for root.key:? ? ? ← 輸入一個(gè)新密碼,如123456
Verifying - Enter pass phrase for root.key: ← 重新輸入一遍密碼
3.2. 創(chuàng)建根證書的申請(qǐng)文件 root.csr
openssl req -new -key root.key -out root.csr
//輸出內(nèi)容為:
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key root.key -out root.csr
Enter pass phrase for root.key:? ? ? ← 輸入前面創(chuàng)建的密碼
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN? ? ? ? ? ? ? ? ? ? ← 國(guó)家代號(hào),中國(guó)輸入CN
State or Province Name (full name) [Some-State]:BeiJing? ? ? ? ← 省的全名,拼音
Locality Name (eg, city) []:BeiJing? ? ? ← 市的全名,拼音
Organization Name (eg, company) [Internet Widgits Pty Ltd]:lanjinglijia? ← 公司英文名
Organizational Unit Name (eg, section) []:? ? ? ? ? ? ? ← 可以不輸入
Common Name (e.g. server FQDN or YOUR name) []:? ? ? ? ← 可以不輸入
Email Address []:guangzhengren@sina.com? ? ? ? ? ? ? ? ← 郵箱
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:? ? ? ? ? ? ? ? ? ? ? ? ← 可以不輸入
An optional company name []:? ? ? ? ? ? ? ? ? ? ? ? ← 可以不輸入
guangzheng@ljlj:~/tmp/ca$
3.3 創(chuàng)建一個(gè)自當(dāng)前日期起為期十年的根證書 root.crt
openssl x509 -req -days 3650 -sha256? -extensions v3_ca -signkey root.key -in root.csr -out root.crt
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl x509 -req -days 3650 -sha256? -extensions v3_ca -signkey root.key -in root.csr -out root.crt
Signature ok
subject=/C=CN/ST=BeiJing/L=BeiJing/O=lanjinglijia/emailAddress=guangzhengren@sina.com
Getting Private key
Enter pass phrase for root.key:? ? ? ? ? ? ? ? ? ? ← 輸入前面創(chuàng)建的密碼
guangzheng@ljlj:~/tmp/ca$
3.4根據(jù)CA證書生成truststore JKS文件 root.truststore
//這一步只針對(duì)雙向認(rèn)證,單向不需要
keytool -keystore root.truststore -keypass 123456 -storepass 123456 -alias ca -import -trustcacerts -file root.crt
鍵入回事后,提示是否信認(rèn)此證書,輸入y, 則生成truststore成功
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ keytool -keystore root.truststore -keypass 123456 -storepass 123456 -alias ca -import -trustcacerts -file root.crt
所有者: EMAILADDRESS=guangzhengren@sina.com, O=lanjinglijia, L=BeiJing, ST=BeiJing, C=CN
發(fā)布者: EMAILADDRESS=guangzhengren@sina.com, O=lanjinglijia, L=BeiJing, ST=BeiJing, C=CN
序列號(hào): bbdba3ba3ca7af4d
有效期開始日期: Sat Jun 24 12:33:22 CST 2017, 截止日期: Tue Jun 22 12:33:22 CST 2027
證書指紋:
MD5: A1:C4:FC:1E:34:0B:CE:CE:64:16:3A:6B:7C:6A:94:E3
SHA1: 7D:BC:AF:9F:70:D1:0B:4C:FE:D6:6E:67:D5:51:53:4B:6A:F6:F3:77
SHA256: 70:1E:44:ED:86:C8:DB:F6:1C:CC:C9:91:70:00:C1:FD:3C:1F:AA:9F:2C:CE:FE:5C:67:D6:2D:F3:5B:B2:85:88
簽名算法名稱: SHA256withRSA
版本: 1
是否信任此證書? [否]:? y
證書已添加到密鑰庫(kù)中
guangzheng@ljlj:~/tmp/ca$
4.制作service服務(wù)器端證書
4.1 創(chuàng)建服務(wù)器證書密鑰 server.key
openssl genrsa -des3 -out server.key 2048
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl genrsa -des3 -out server.key 2048
Generating RSA private key, 2048 bit long modulus
........................................................................................................+++
...........................................+++
e is 65537 (0x10001)
Enter pass phrase for server.key:? ? ? ? ? ? ? ← 輸入前面創(chuàng)建的密碼
Verifying - Enter pass phrase for server.key:? ? ? ? ? ← 重新輸入一遍密碼
guangzheng@ljlj:~/tmp/ca$
4.2 創(chuàng)建服務(wù)器證書的申請(qǐng)文件 server.csr
openssl req -new -key server.key -out server.csr
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key server.key -out server.csr
Enter pass phrase for server.key:? ? ? ? ? ? ? ? ? ? ? ? ← 輸入前面創(chuàng)建的密碼
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN? ? ? ? ? ? ? ? ? ? ? ? ← 國(guó)家名稱,中國(guó)輸入CN
State or Province Name (full name) [Some-State]:BeiJing? ? ? ? ? ? ← 省名,拼音
Locality Name (eg, city) []:BeiJing? ? ? ? ? ? ? ? ? ? ? ? ← 市名,拼音
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ljlj? ? ? ? ← 公司英文名
Organizational Unit Name (eg, section) []:? ? ? ? ? ? ? ? ? ← 可以不輸入
Common Name (e.g. server FQDN or YOUR name) []:tomcat.loc? ? ? ← 服務(wù)器主機(jī)名(或者IP),若填寫不正確,瀏覽器會(huì)報(bào)告證書無(wú)效,但并不影響使用
Email Address []:guangzhengren@sina.com? ? ? ? ? ? ? ? ? ? ← 郵箱
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:? ? ? ? ? ? ? ? ? ? ? ? ? ? ← 可以不輸入
An optional company name []:? ? ? ? ? ? ? ? ? ? ? ? ? ? ← 可以不輸入
guangzheng@ljlj:~/tmp/ca$
4.3 創(chuàng)建自當(dāng)前日期起有效期為期十年的服務(wù)器證書 server.crt
openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in server.csr -out server.crt
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in server.csr -out server.crt
Signature ok
subject=/C=CN/ST=BeiJing/L=BeiJing/O=ljlj/CN=tomcat.loc/emailAddress=guangzhengren@sina.com
Getting CA Private Key
Enter pass phrase for root.key:? ? ? ? ? ? ? ? ? ? ? ? ← 輸入前面創(chuàng)建的密碼
guangzheng@ljlj:~/tmp/ca$
4.4 導(dǎo)出.p12文件 server.p12
openssl pkcs12 -export -in server.crt -inkey server.key -out? server.p12 -name "server"
根據(jù)命令提示,輸入server.key密碼,創(chuàng)建p12密碼
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl pkcs12 -export -in server.crt -inkey server.key -out? server.p12 -name "server"
Enter pass phrase for server.key:
Enter Export Password:
Verifying - Enter Export Password:
guangzheng@ljlj:~/tmp/ca$
4.5 將.p12 文件導(dǎo)入到keystore JKS文件 server.keystore
keytool -importkeystore -v -srckeystore? server.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore server.keystore -deststoretype jks -deststorepass 123456
這里srcstorepass后面的123456為server.p12的密碼deststorepass后的123456為keyStore的密碼
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ keytool -importkeystore -v -srckeystore? server.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore server.keystore -deststoretype jks -deststorepass 123456
已成功導(dǎo)入別名 server 的條目。
已完成導(dǎo)入命令: 1 個(gè)條目成功導(dǎo)入, 0 個(gè)條目失敗或取消
[正在存儲(chǔ)server.keystore]
guangzheng@ljlj:~/tmp/ca$
5.制作client客戶端證書
5.1 創(chuàng)建客戶端證書密鑰文件 client.key
openssl genrsa -des3 -out client.key 2048
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl genrsa -des3 -out client.key 2048
Generating RSA private key, 2048 bit long modulus
..............................+++
.+++
e is 65537 (0x10001)
Enter pass phrase for client.key:? ? ? ? ? ← 輸入一個(gè)新密碼
Verifying - Enter pass phrase for client.key:? ? ? ← 重新輸入一遍密碼
guangzheng@ljlj:~/tmp/ca$
5.2 創(chuàng)建客戶端證書的申請(qǐng)文件 client.csr
openssl req -new -key client.key -out client.csr
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key client.key -out client.csr
Enter pass phrase for client.key:? ? ? ? ? ? ? ? ? ? ? ← 輸入上一步中創(chuàng)建的密碼
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN? ? ? ? ? ? ? ? ? ? ? ? ← 國(guó)家名稱,中國(guó)輸入CN
State or Province Name (full name) [Some-State]:BeiJing? ? ? ? ? ? ← 省名稱,拼音
Locality Name (eg, city) []:BeiJing? ? ? ? ? ? ? ? ? ? ? ? ← 市名稱,拼音
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ljlj? ? ? ? ← 公司英文名
Organizational Unit Name (eg, section) []:? ? ? ? ? ? ? ? ? ← 可以不填
Common Name (e.g. server FQDN or YOUR name) []:guangzhengren? ? ? ? ← 自己的英文名,可以隨便填
Email Address []:guangzhengren@sina.com? ? ? ? ? ? ? ? ? ? ← 電子郵箱,可以隨便填
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:? ? ? ? ? ? ? ? ? ? ? ? ? ? ← 可以不填
An optional company name []:? ? ? ? ? ? ? ? ? ? ? ? ? ? ← 可以不填
guangzheng@ljlj:~/tmp/ca$
5.3 創(chuàng)建一個(gè)自當(dāng)前日期起有效期為十年的客戶端證書 client.crt
openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in client.csr -out client.crt
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in client.csr -out client.crt
Signature ok
subject=/C=CN/ST=BeiJing/L=BeiJing/O=ljlj/CN=guangzhengren/emailAddress=guangzhengren@sina.com
Getting CA Private Key
Enter pass phrase for root.key:? ? ? ? ? ? ? ? ? ? ? ? ← 輸入上面創(chuàng)建的密碼
guangzheng@ljlj:~/tmp/ca$
5.4 導(dǎo)出.p12文件 client.p12
openssl pkcs12 -export -in client.crt -inkey client.key -out? client.p12 -name "client"
根據(jù)命令提示,輸入client.key密碼,創(chuàng)建p12密碼。
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl pkcs12 -export -in client.crt -inkey client.key -out? client.p12 -name "client"
Enter pass phrase for client.key:
Enter Export Password:
Verifying - Enter Export Password:
guangzheng@ljlj:~/tmp/ca$
5.5 生成curl所需pem文件:
openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA ./root.crt -CAkey ./root.key -CAcreateserial -in client.csr -out client.pem
//輸出內(nèi)容
guangzheng@ljlj:~/tmp/ca$ openssl x509 -req -days 3650 -sha256? -extensions v3_req -CA ./root.crt -CAkey ./root.key -CAcreateserial -in client.csr -out client.pem
Signature ok
subject=/C=CN/ST=BeiJing/L=BeiJing/O=ljlj/CN=guangzhengren/emailAddress=guangzhengren@sina.com
Getting CA Private Key
Enter pass phrase for ./root.key:? ← 輸入上面創(chuàng)建的密碼
guangzheng@ljlj:~/tmp/ca$
6.完成后的文件夾中應(yīng)該包含:
guangzheng@ljlj:~/tmp/ca$ ls
client.crt? client.key? client.pem? root.csr? root.srl? ? ? ? server.crt? server.key? ? ? server.p12
client.csr? client.p12? root.crt? ? root.key? root.truststore? server.csr? server.keystore
7.配置tomcat? ? 打開tomcat的配置文件server.xml? ??
guangzheng@ljlj:~/tmp/ca$ vim /usr/local/tomcat/conf/server.xml? ??
找到:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"? ? ? ? ? ? ? maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />? ? ? ? ? ? ??
修改為:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="/home/guangzheng/tmp/ca/server.keystore" keystorePass="123456"
truststoreFile="/home/guangzheng/tmp/ca/root.truststore" truststorePass="123456"
clientAuth="true" sslProtocol="TLS"? />
重啟tomcat
8.測(cè)試是否配置成功
編寫php代碼如下:
<?php
header("Content-type:text/html;charset=utf-8");
/************************curl雙向認(rèn)證常量配置start**************************/
//根證書路徑
define('HTTPS_CAINFO', '/home/guangzheng/tmp/ca/root.crt');
//client.pem文件路徑
define('HTTPS_SSLCERT', '/home/guangzheng/tmp/ca/client.pem');
//私鑰文件路徑
define('HTTPS_SSLKEY', '/home/guangzheng/tmp/ca/client.key');
//私鑰密碼
define('HTTPS_SSLKEYPASSWD', '123456');
/************************curl雙向認(rèn)證常量配置end**************************/
$wxpayUrl = 'https://tomcat.loc:8443/';//項(xiàng)目地址
$token = md5('BillCompareServletdoPostcasher');? //驗(yàn)證token
$array = array(
'token' => $token
);
$wechat = doPost($wxpayUrl,$array);
var_dump($wechat);
/**
* [方法描述] CURL模擬post請(qǐng)求,執(zhí)行https雙向認(rèn)證
* @param [string] $url? 請(qǐng)求路徑
* @param [array] $fields? 請(qǐng)求參數(shù) array( 'data' => '111' );
* @param [array ] $extraheader [header頭部的重寫]
* @param [const] 常量定義 HTTPS_CAINFO 根證書 例:/home/ljlia/rgz/ca/root.crt
* @param [const] 常量定義 HTTPS_SSLCERT client.pem文件路徑 例:/home/ljlia/www/pay/client.pem
* @param [const] 常量定義 HTTPS_SSLCERTPASSWD client證書密碼
* @param [const] 常量定義 HTTPS_SSLKEY 私鑰文件路徑
* @param [const] 常量定義 HTTPS_SSLKEYPASSWD 私鑰密碼
* @return? 接口返回的數(shù)據(jù)
*/
function doPost($url, $fields, $extraheader = array()){
$fields = http_build_query($fields);? ? //將數(shù)據(jù)進(jìn)行URL-encode轉(zhuǎn)換
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_PORT, 8443);//指定端口
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );? //post參數(shù)
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraheader);? //設(shè)置一個(gè)header中傳輸內(nèi)容的數(shù)組。
curl_setopt($ch, CURLOPT_SSLVERSION, 1);//傳遞一個(gè)包含SSL版本的長(zhǎng)參數(shù)。默認(rèn)PHP將被它自己努力的確定,在更多的安全中你必須手工設(shè)置
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); //不信任任何證書
curl_setopt($ch, CURLOPT_CAINFO, HTTPS_CAINFO); //根證書路徑
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 檢查證書中是否設(shè)置域名,0不驗(yàn)證
curl_setopt($ch, CURLOPT_VERBOSE, 1); //debug模式
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, HTTPS_SSLCERT); //client.pem文件路徑
// curl_setopt($ch, CURLOPT_SSLCERTPASSWD, HTTPS_SSLCERTPASSWD); //client證書密碼
curl_setopt($ch, CURLOPT_SSLKEY, HTTPS_SSLKEY);//私鑰文件路徑
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, HTTPS_SSLKEYPASSWD);//私鑰密碼
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 如果成功只將結(jié)果返回,不自動(dòng)輸出任何內(nèi)容。
$output = curl_exec($ch);
if(curl_errno($ch) != 0) $output = 'Curl error: ' . curl_error($ch);//curl錯(cuò)誤信息
curl_close($ch);
return $output;
}
?>
運(yùn)行以上php代碼查看是否配置成功
注意:若要在本地瀏覽器查看網(wǎng)頁(yè),請(qǐng)將根證書和客戶端證書導(dǎo)入到瀏覽器中