HTTPS工作原理以及Tomcat开启HTTPS单向认证
本文由 小茗同学 发表于 2016-10-13 浏览(1020)
最后修改 2018-01-07 标签:tomcat https 开启

HTTPS简单介绍

HTTPS是加密版的HTTPS,是为了解决HTTPS明文传输不安全为题而诞生的。HTTP默认端口是80,HTTPS默认端口是443。早期使用SSL(Secure Sockets Layer)协议,后期使用TLS(Transport Layer Security)协议。

SSL协议既用到了对称加密也用到了非对称加密(公钥加密),在建立传输链路时,SSL首先对密钥进行非对称加密,链路建立好之后,SSL对传输内容使用对称加密。

HTTPS的认证包括单向认证和双向认证,一般web网站都使用单向认证,双向认证要求客户端和服务端都有证书。

HTTP 工作原理

本小结内容摘抄自网络。

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。握手过程的简单描述如下:

  1. 浏览器将自己支持的一套加密规则发送给网站。
  2. 网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
  3. 获得网站证书之后浏览器要做以下工作:
    a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。

    b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。

    c) 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。

  4. 网站接收浏览器发来的数据之后要做以下的操作:

    a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。

    b) 使用密码加密一段握手消息,发送给浏览器。

  5. 浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

tomcat配置https

第一步:创建密钥

创建 keystore,使用JAVA_HOME/bin下的keytool.exe(绝大部分人都应该已经配置了环境变量,所以可以直接使用),打开CMD输入如下命令:

keytool -genkey -alias tomcat -keyalg RSA -validity 36500

首先输入密钥口令,然后填一些没用的信息,然后输入y确定,最后设置tomcat口令,直接回车会和密钥口令相同,文件会生成在"C:\Users\用户名\.keystore"

第二步:导出证书

执行如下命令,其中storepass是指上面指定的密码:

keytool -export -alias tomcat -keystore c:\Users\LXA\.keystore -file c:\tomcat.cer -storepass 123456

这个证书是将来给访问者导入到浏览器用的。

第三步:配置tomcat

打开server.xml,下面这段代码默认是注释的,取消注释即可,然后在最后面增加keystoreFilekeystorePass的配置,前者按下面填写,后者填写你第一步中设置的密码:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
			   maxThreads="150" scheme="https" secure="true"
			   clientAuth="false" sslProtocol="TLS"
			   keystoreFile="${user.home}/.keystore" keystorePass="123456"/>

注意,如果你修改了端口号(比如把8443修改为443),那么其他所有redirectPort="8443"的地方都要相应改成redirectPort="443"

然后给你项目的web.xml增加如下配置,目的是让http自动跳转到https:

<!-- Authorization setting for SSL -->
<login-config>
	<auth-method>CLIENT-CERT</auth-method>
	<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
	<web-resource-collection >
		<web-resource-name >SSL</web-resource-name>
		<url-pattern>/*</url-pattern>
	</web-resource-collection>
	<user-data-constraint>
		<transport-guarantee>CONFIDENTIAL</transport-guarantee>
	</user-data-constraint>
</security-constraint>

然后启动tomcat,访问: https://localhost:8443/ 虽然可以访问,但是有警告:

这是因为你的证书不受信任,需要手动导入上面第二步生成的证书。

第四步:导入证书

双击证书文件一直下一步即可,这里需要特别注意,在选择存储位置的时候,必须手动指定到受信任的根证书颁发机构,否则证书还是不受信任。

导入之后重启浏览器重新访问 https://localhost:8443/ ,此时应该没问题了:

如果还是有问题

如果仍然提示不受信任,可以打开Chrome的开发者工具,会给出一些错误原因,比如说,如果你安装证书的时候没有手动指定存储路径的话就会出现如下错误:

查看已导入的证书:

几个注意事项:

  • 重新生成密钥一定要删除旧的密钥;
  • 重新生成密钥之后必须重启tomcat;
  • 重新导入证书之后必须重启浏览器;
  • 如果之前错误的将证书安装到了中间证书颁发机构而不是受信任的根证书颁发机构,一定要将前者里面的无用证书删掉,否则会影响正常的证书;

可能碰到的错误

以下内容是网上复制的,未亲测!

这时候如果用程序去访问可能还会抛证书不信任的异常:

sun.security.validator.ValidatorException: PKIX path building failed...

需要将生成的证书(tomcat.cer)导入到jdk中:

keytool -import -alias tomcat -file "C:\tomcat.cer" -keystore "C:\Users\LXA\.keystore" -storepass 123456

其它错误:

  • 如果抛 No subject alternative names present 请在生成keystore时注意CN必须要为域名(或机器名称)例如 localhost 不能为IP
  • 如果抛 No name matching localhost found 表示你生成keystore是CN的名称和你访问的名称不一致

百度也是https为何不需要导入证书?

证书为什么还要购买

https://bbs.kechuang.org/t/79505

参考

http://juncao2011.iteye.com/blog/973988

Https单向认证和双向认证