1.明确https域名,如:tomcat.loc,生成证书时使用
2.创建证书目录
//进入tmp目录
cd /home/guangzheng/tmp
//创建ca目录,存放证书相关文件
mkdir ca
//进入ca
cd ca
3.制作根证书
3.1 创建根证书密钥文件(自己做CA) root.key
openssl genrsa -des3 -out root.key 2048
//输出内容为:
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: ← 输入一个新密码,如123456
Verifying - Enter pass phrase for root.key: ← 重新输入一遍密码
3.2. 创建根证书的申请文件 root.csr
openssl req -new -key root.key -out root.csr
//输出内容为:
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key root.key -out root.csr
Enter pass phrase for root.key: ← 输入前面创建的密码
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 ← 国家代号,中国输入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 创建一个自当前日期起为期十年的根证书 root.crt
openssl x509 -req -days 3650 -sha256 -extensions v3_ca -signkey root.key -in root.csr -out root.crt
//输出内容
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: ← 输入前面创建的密码
guangzheng@ljlj:~/tmp/ca$
3.4根据CA证书生成truststore JKS文件 root.truststore
//这一步只针对双向认证,单向不需要
keytool -keystore root.truststore -keypass 123456 -storepass 123456 -alias ca -import -trustcacerts -file root.crt
键入回事后,提示是否信认此证书,输入y, 则生成truststore成功
//输出内容
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
发布者: EMAILADDRESS=guangzhengren@sina.com, O=lanjinglijia, L=BeiJing, ST=BeiJing, C=CN
序列号: 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
证书已添加到密钥库中
guangzheng@ljlj:~/tmp/ca$
4.制作service服务器端证书
4.1 创建服务器证书密钥 server.key
openssl genrsa -des3 -out server.key 2048
//输出内容
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: ← 输入前面创建的密码
Verifying - Enter pass phrase for server.key: ← 重新输入一遍密码
guangzheng@ljlj:~/tmp/ca$
4.2 创建服务器证书的申请文件 server.csr
openssl req -new -key server.key -out server.csr
//输出内容
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key server.key -out server.csr
Enter pass phrase for server.key: ← 输入前面创建的密码
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 ← 国家名称,中国输入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 ← 服务器主机名(或者IP),若填写不正确,浏览器会报告证书无效,但并不影响使用
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 创建自当前日期起有效期为期十年的服务器证书 server.crt
openssl x509 -req -days 3650 -sha256 -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in server.csr -out server.crt
//输出内容
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: ← 输入前面创建的密码
guangzheng@ljlj:~/tmp/ca$
4.4 导出.p12文件 server.p12
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name "server"
根据命令提示,输入server.key密码,创建p12密码
//输出内容
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 文件导入到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的密码
//输出内容
guangzheng@ljlj:~/tmp/ca$ keytool -importkeystore -v -srckeystore server.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore server.keystore -deststoretype jks -deststorepass 123456
已成功导入别名 server 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
[正在存储server.keystore]
guangzheng@ljlj:~/tmp/ca$
5.制作client客户端证书
5.1 创建客户端证书密钥文件 client.key
openssl genrsa -des3 -out client.key 2048
//输出内容
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: ← 输入一个新密码
Verifying - Enter pass phrase for client.key: ← 重新输入一遍密码
guangzheng@ljlj:~/tmp/ca$
5.2 创建客户端证书的申请文件 client.csr
openssl req -new -key client.key -out client.csr
//输出内容
guangzheng@ljlj:~/tmp/ca$ openssl req -new -key client.key -out client.csr
Enter pass phrase for client.key: ← 输入上一步中创建的密码
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 ← 国家名称,中国输入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 创建一个自当前日期起有效期为十年的客户端证书 client.crt
openssl x509 -req -days 3650 -sha256 -extensions v3_req -CA root.crt -CAkey root.key -CAcreateserial -in client.csr -out client.crt
//输出内容
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: ← 输入上面创建的密码
guangzheng@ljlj:~/tmp/ca$
5.4 导出.p12文件 client.p12
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "client"
根据命令提示,输入client.key密码,创建p12密码。
//输出内容
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
//输出内容
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: ← 输入上面创建的密码
guangzheng@ljlj:~/tmp/ca$
6.完成后的文件夹中应该包含:
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.测试是否配置成功
编写php代码如下:
<?php
header("Content-type:text/html;charset=utf-8");
/************************curl双向认证常量配置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双向认证常量配置end**************************/
$wxpayUrl = 'https://tomcat.loc:8443/';//项目地址
$token = md5('BillCompareServletdoPostcasher'); //验证token
$array = array(
'token' => $token
);
$wechat = doPost($wxpayUrl,$array);
var_dump($wechat);
/**
* [方法描述] CURL模拟post请求,执行https双向认证
* @param [string] $url 请求路径
* @param [array] $fields 请求参数 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 接口返回的数据
*/
function doPost($url, $fields, $extraheader = array()){
$fields = http_build_query($fields); //将数据进行URL-encode转换
$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参数
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraheader); //设置一个header中传输内容的数组。
curl_setopt($ch, CURLOPT_SSLVERSION, 1);//传递一个包含SSL版本的长参数。默认PHP将被它自己努力的确定,在更多的安全中你必须手工设置
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); //不信任任何证书
curl_setopt($ch, CURLOPT_CAINFO, HTTPS_CAINFO); //根证书路径
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名,0不验证
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); // 如果成功只将结果返回,不自动输出任何内容。
$output = curl_exec($ch);
if(curl_errno($ch) != 0) $output = 'Curl error: ' . curl_error($ch);//curl错误信息
curl_close($ch);
return $output;
}
?>
运行以上php代码查看是否配置成功
注意:若要在本地浏览器查看网页,请将根证书和客户端证书导入到浏览器中