有一天,我在开心的写代码,在jetty上做了类似302的重定向,不过是重定向到一个https的页面上,但是这个https页面直接访问是正常的,但是由jetty做重定向以后就不对了,显示错误:
Unauthorized
This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn‘t understand how to supply the credentials required.
Additionally, a 401 Unauthorized error was encountered while trying to use an ErrorDocument to handle the request.
很不开心,琢磨了一会,发现是jetty并没有接受证书,因为这个https页面的证书是自签名的,因此并没有被jdk所信任:
那么我们重头开始做一遍:
指令列表
- openssl genrsa -out rootkey.pem 2048
生成根证书的密匙。
- openssl req -x509 -new -key rootkey.pem -out root.crt
生成根证书。注意-x509,与步骤4和7不同。需要输入机构相关信息。
- openssl genrsa -out clientkey.pem 2048
生成客户端的密匙。
- openssl req -new -key clientkey.pem -out client.csr 生成客户端证书的请求文件。请求根证书来签发。
- openssl x509 -req -in client.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out client.crt
用根证书来签发客户端请求文件,生成客户端证书client.crt。
- openssl genrsa -out serverkey.pem 2048
生成服务器端的密匙。
- openssl req -new -key serverkey.pem -out server.csr
生成服务器端证书的请求文件。请求根证书来签发。
- openssl x509 -req -in server.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out server.crt
用根证书来签发服务器端请求文件,生成服务器端证书server.crt。
- openssl pkcs12 -export -in client.crt -inkey clientkey.pem -out client.pkcs12
打包客户端资料为pkcs12格式(client.pkcs12)。需要输入密码,请记住。
- openssl pkcs12 -export -in server.crt -inkey serverkey.pem -out server.pkcs12
打包服务器端资料为pkcs12格式(server.pkcs12 )。需要输入密码,请记住。
- keytool -importkeystore -srckeystore client.pkcs12 -destkeystore client.jks -srcstoretype pkcs12
生成客户端keystore(client.jks)。使用keytool的importkeystore指令。pkcs12转jks。需要pkcs12密码和jks密码。
- keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12
做完这些事情以后,我们有了根证书,还有了服务器证书和客户端的证书,但是这些证书并不受jdk认可,因此我们需要把这份keystore导入到jdk中去,
那么默认的地址是$JAVA_HOME/jre/lib/security/cacerts中,因此,我们可以把证书的keystore导入进来:
keytool -import -trustcacerts -alias clientkey -file client.crt -keystore ‘/usr/lib/jvm/java-1.6.0-openjdk-amd64/jre/lib/security/cacerts‘
keytool -import -trustcacerts -alias serverkey -file server.crt -keystore ‘/usr/lib/jvm/java-1.6.0-openjdk-amd64/jre/lib/security/cacerts‘
然后再次访问,就OK了~
当然也有其他的方案,比如让maven或者java忽略对证书合法性的检查,这类我们没有做研究。有兴趣的话可以分享一下。