双向认证原理
双向认证的
- 浏览器下载 “服务端公钥证书” ,据此证书,发送密文给服务端,服务端用“服务端公钥”解密签名和密文
- 浏览器 先加载 “客户私钥证书” ,据此证书,解密服务端的 “客户公钥证书”加密的签名和密文
tomcat的双向认证
tomcat双向认证配置与ngnix 不一样,利用了java 的keystore ,1个keystore 就够了。
keystore 秘钥库
java的keystore是一个库文件, 里面可以存放多个非对称秘钥或对称秘钥(包含公钥和私钥),管理起来很方便。需要证书时,从keystore中用特定的非对称秘钥生成某种格式的证书即可。keytool 工具有很多命令,网上可以查。
所以 keystore中必须放两组秘钥: 1.服务器非对称秘钥,2. 验证客户端秘钥的公钥
另外制作一个p12格式的私钥证书给客户端,单独导入到浏览器中,或客户端 即可
参考
我看了几十篇文章,这篇文章最简洁,但是我还是要根据自己的情况进行一些调整
https://blog.youkuaiyun.com/u014175785/article/details/50680604
脚本
1. 新建一个目录用来存放制作好的秘钥库和证书
mkdir d:/ssl
cd ssl
2. 生成 server 秘钥库和 server 秘钥
keytool -validity 3650 -genkey -v -alias server -keyalg RSA -keystore server.keystore -dname "CN=www.xxx.com,O=lh, C=CN" -storepass 123456 -keypass 123456 -storetype PKCS12
# 默认是jks格式的秘钥库 可以使用PKCS12 行业标准格式的秘钥库
# 如果不添加这个 “-storetype PKCS12” 参数 可以用下面的命令进行转换
keytool -importkeystore -srckeystore server.keystore -destkeystore server.keystore -deststoretype pkcs12
3. 生成客户端秘钥库
keytool -genkey -keystore cert.p12 -alias iekey -storepass 123456 -keyalg RSA -storetype PKCS12 -validity 3650 -dname "OU=Manager,CN=www.xxx.com, O=lh, C=CN"
4. 用客户端密钥对制作客户公钥证书
keytool -export -file cert.cer -keystore cert.p12 -alias iekey -storepass 123456 -storetype PKCS12 -rfc
5. 从客户公钥证书中提取 公钥和签名导入 server秘钥库
keytool -import -alias iekey -v -file cert.cer -keystore server.keystore -storepass 123456
6. 用邮件、网盘或者qq 发送 cert.p12 文件给客户
#删除key
keytool -delete -alias mykey -keystore server.keystore -storepass 123456
#查看秘钥库
keytool -list -keystore server.keystore -storepass 123456
tomcat的配置文件
server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="D:/ssl/server.keystore" keystorePass="123456"
truststoreFile="D:/ssl/server.keystore" truststorePass="123456"/>
多域名配置时 这里不要加 address 属性 , 只要改web.xml 即可
多域名时参考如下配置
- 删除原来的
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
- 添加
Host .name 约束了可以访问的域名
Host . Context .docBase 属性是代码存放目录
Host . Context .path 属性是代码 域名后的虚拟路径,一般部署时没有,开发时才有
<Host appBase="webapps" autoDeploy="true" name="www.zdy.com" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt" /> <Context docBase="spring3" path="" reloadable="true" source="org.eclipse.jst.jee.server:spring3" /> </Host> <Host appBase="webapps" autoDeploy="true" name="www.hyl.com" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt" /> <Context docBase="hjsp" path="" reloadable="true" source="org.eclipse.jst.jee.server:hyl.framework.hjsp" /> </Host>
web.xml 添加ssl 启用配置
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern><!-- 全站使用SSL -->
</web-resource-collection>
<user-data-constraint>
<description>SSL required</description>
<!-- CONFIDENTIAL: 要保证服务器和客户端之间传输的数据不能够被修改,且不能被第三方查看到 -->
<!-- INTEGRAL: 要保证服务器和client之间传输的数据不能够被修改 -->
<!-- NONE: 指示容器必须能够在任一的连接上提供数据。(即用HTTP或HTTPS,由客户端来决定)-->
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
```