您的位置:首页 > 运维架构 > Tomcat

Tomcat中的ssl加密配置

2009-04-21 17:20 316 查看
SSL简介
SSL, 或者Secure Socket Layer,是一种允许web浏览器和web服务器通过一个安全的连接进行 交流的技术。这意味着将被发送的数据在一端被翻译成密码,传送出去,然后在另一端解开密码, 再进行处理。这是一个双向的过程,也就是浏览器和服务器都需要在发送数据之前对它们进行加密。
SSL协定的另一个重要方面是认证(Authentication)。这就是说,在你开始试图通过一个安连接 与一个web服务器交流的时候,这个服务器会要求你的浏览器出示一组证件,通过“鉴定”的方式来证明这 就是你所声明的网站。在某些情况下,服务器还会要求你的web浏览器的认证书,证明你就是你所说的那 个人。这就是所知的“客户认证”,尽管实际情况中,更多地用在商务-对-商务(B2B)交易,而不是对个人 用户。大多数有SSL功能的web服务器不要求客户认证(Client Authentication)。
SSL 和 Tomcat
必须要注意,配置Tomcat来利用secure sockets仅仅在它作为一个独立的web服务器时才有必要。 当Tomcat主要作为在另外一个web服务器,如Apache 或Microsoft IIS, 后面的Servlet/JSP容器 运行时,通常有必要把主要的web服务器配置来处理与用户的SSL连接。通常,这个服务器会对所有的 SSL-相关的功能进行交涉,然后再把对Tomcat容器的请求解密后传递过去。同样,Tomcat会返回 明码的回应,这个回应将被加密后才被送到用户浏览器。在这样的环境下,Tomcat知道与主要web服务器 和客户的交流是通过一个安全连接才发生的(因为你的程序需要询问这些情况),但是它本身并没有参与 加密和解密。
认证书:Certificate
为了能实施SSL,一个web服务器对每个接受安全连接的外部接口(IP 地址)必须要有相应的认 证书(Certificate)。关于这个设计的理论是一个服务器必须提供某种合理的保证以证明这个服务器的 主人就是你所认为的那个人,特别是在接收任何敏感信息之前要这样做。关于Certificates的更广泛 的解释超过了这个文档资料的范围,就把一个认证书当作一个英特网地址的“数码驾驶执照”。这个认证书 要陈述与这个网站相关联的公司,以及这个网站的所有者或系统管理员的一些基本联系信息。
这个"驾驶执照"由所有人以密码方式签字,其他人非常难伪造。对于进行电子商务 (e-commerce)的网站,或其他身份认证至关重要的任何商业交易,认证书要向大家所熟知的认证权威 (Certificate Authority (CA))如VeriSign或Thawte来购买。这样的认证书可用电子 技术证明属实——实际上,认证权威单位会担保它发出的认证书的真实性,如果你信任发出认证书的 认证权威单位的话,你就可以相信这个认证书是有效的。
在许多情况下,认证并不是真正使人担忧的事。系统管理员或许只想要保证被服务器传送和接收的 数据是秘密的,不会被连接线上的偷窃者盗窃到。庆幸的是,Java提供相对简单的被称 为keytool的命令行工具,可以简单地产生“自己签名”的认证书。自己签名的认证书 只是用户产生的认证书,没有正式在大家所熟知的认证权威那里注册过,因此不能确保它的真实性。 认证也许很重要,也许不重要,完全决定于你的需要。
使用SSL需要考虑的地方
用户第一次试图到你的网站访问被安全保卫的页面时,他(她)通常会被要求提供关于认证的 详细信息(如公司名称和联系姓名),并询问他(她)是否愿意接受这个认证的合法性,并继续进行交易。 一些浏览器会提供一个选项来永久地接受所给的认证的合法性,这样一来用户就不用在每次访问你的网站 时麻烦地去填写认证信息。有的浏览器没有这一选项。一旦用户认可后,这个认证至少在整个浏览器 会话期间被认为是合法的。
虽然SSL协议的设计尽量做到既安全又高效,但是加密和解密是复杂耗时的计算过程。通常没有必要让整个 网站都通过SSL来传输,开发人员可以选择部分网页用SSL,部分网页不用SSL。对于一个相对繁忙的网站 来说,可以选择保护那些比较敏感的信息,如登陆、个人信息、购物车、付账、信用卡等。那些网页只要 把网页地址里http:改为https:,浏览器就会自动把信息按照指定的 协议传输出去。
最后,使用根据网名决定的虚拟主机来进行安全连接可能会出现问题。这是SSL协定本身的设计局限。 SSL handshake,就是客户浏览器接受服务器认证,在HTTP请求访问之前必须产生。因此,包含虚拟 主机名字的请求信息在认证之前不能被确定,所以不可能给单个IP地址分配多个认证书。如果在单个IP 地址上的所有的虚拟主机需要对照同一个认证书来认证的话,再添加多个虚拟主机不应该干扰服务器上 正常的SSL操作。不过要当心,大多数的客户浏览器会按认证书上列出的domain names(主要是官方的, CA-签署的认证书)对照比较服务器的domain name。如果领域名(domain names)不相配,这些浏览器 会向客户端用户显示警告。总的来说,只有address-based虚拟主机通常和SSL一起在生产环境中 被使用。
产生 Keystore
Tomcat 现在只支持 JKS或PKCS12 格式的keystores. JKS格式是 Java 的标准 KeyStore格式,它可以用 Java 的 keytool 来产生。这个工具在 Java 的 bin 目录里。 PKCS12 格式时互联网的标准,可以用 OpenSSL 和微软的 Key-Manager来修改。
要从头开始产生一个新的keystore,包含一个自签的认证书,从一个终端命令行执行下面的命令:
Window%JAVA_HOME%/bin/keytool -genkey -alias tomcat -keyalg RSA
Unix%JAVA_HOME%/bin/keytool -genkey -alias tomcat -keyalg RSA
( 应该把RSA运算法则作为主要安全运算法则,这保证了与其它服务器和组件的兼容性。)
这个命令会在用户的home directory产生一个叫做" .keystore " 的新文件。要指定一个不同的位置(location)或文件名,在上面所示的keytool 命令里添加-keystore参数,后面紧跟着你的keystore文件的全部路径名。你还需要把 这个新的位置在server.xml配置文件中反映出来,这在后面将有描述。例如:
Window%JAVA_HOME%/bin/keytool -genkey -alias tomcat -keyalg RSA /
-keystore /path/to/my/keystore
Unix%JAVA_HOME%/bin/keytool -genkey -alias tomcat -keyalg RSA /
-keystore /path/to/my/keystore
在执行这个命令后,你首先被要求出示keystore密码。Tomcat使用的默认密码是 " changeit "(全都是小写字母),如果你愿意,你可以指定你自己的 密码。你还需要在server.xml配置文件里指定自己的密码,这在以后会有描述。
下一步,你会被要求出示关于这个认证书的一般性信息,如公司,联系人名称,等等。这些信息会 显示给那些试图访问你程序里安全网页的用户,以确保这里提供的信息与他们期望的相对应。
最后,你会被要求出示密钥(key)密码,也就是这个认证书所特有的密码(与其它的 储存在同一个keystore文件里的认证书不同)。你必须在这里使用与keystore 密码相同的密码。(目前,keytool会提示你按ENTER键会自动帮你做这些)。
如果一切顺利,你现在就拥有了一个可以被你的服务器使用的有认证书的keystore文件。
注意: 你的 private key 的密码和 keystore 的密码应该相同。 如果不同的话你会得到一下错误信息: java.io.IOException: Cannot recover key 这是一个已知的错误,详细请看: Bugzilla issue 38217
Edit the Tomcat Configuration File
最后的步骤是把你的secure socket配置在$CATALINA_HOME/conf/server.xml文件里, $CATALINA_HOME代表你在其中安装Tomcat 5 的目录。一个例子是SSL连接器 的<Connector>元素被包括在和Tomcat一起安装的缺省server.xml文件里。 它看起来象是这样:
<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<!--
<Connector
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true";
clientAuth="false" sslProtocol="TLS"/>
-->
你会注意到Connector元素本身,其默认形式是被注释掉的(commented out),所以你需要把它周围 的注释标志删除掉。然后,你可以根据需要客户化(自己设置)特定的属性。关于各种选项的详细信息, 请查阅Server Configuration Reference 。下面的讨论 仅仅涵盖设置SSL通信(communication)时大家最感兴趣的那些属性。
这个port属性(默认值是8443)是 TCP/IP端口数码,Tomcat在其上监听安全连接。 你可以把它更改成任何你愿意要的数值(如默认的https通信,数目是443)。不过,在许 多操作系统中,要想在比1024小的端口数码上运行Tomcat,需要特殊的设置(它超出了这个文档资料 的范围)。
在完成这些配置更改后,你必须象通常那样重新启动Tomcat,然后你就可以工作了。 你应该可以通过SSL访问Tomcat支持的任何web应用程序。例如,试一下下面的指令: https://localhost:8443 你应该看到通常的Tomcat splash页面(除非你修改过ROOT web应用程序)。如果不行的话, 下面的章节包含一些排除故障的提示。
安装和获取认证权威颁发的认证书
产生一个认证签名请求 (CSR)
为了从你选择的认证权威那里获得认证书,你必须产生一个所谓的认证签名请求(Certificate Signing Request (CSR))。这个认证签名请求被认证权威用来产生鉴定你的网站是“安全的”的认证书。 按照下列步骤产生一个CSR:
&8226; 产生一个局部认证书(如前面章节描述那样):
keytool -genkey -alias tomcat -keyalg RSA /
-keystore <your_keystore_filename>
&8226; 注意:在某些情况下, 要产生一个工作认证书,你必须在“"first- and lastname" field 键入你的网站的域名 (例如www.jaxmao.org)。
&8226; 然后用下列指令产生CSR :
keytool -certreq -keyalg RSA -alias tomcat
-file certreq.csr /
-keystore <your_keystore_filename>
执行这个命令之后你会得到一个文件叫 certreq.csr。然后你可以到发送到认证权威, 然后你就可以得到你的认证书。具体步骤可以参考他们的网站的帮助文件。
导入认证书
现在你有了认证书,你可以把它输入到你局部的keystore里。首先你必须输入一个叫做证书链 Chain Certificate 或 Root Certificate 到你的 keystore 里去。在这之后,你可以开始 输入你的认证书。
&8226; 从你获得认证书的认证权威那里下载一个Chain Certificate 。
For Verisign.com commercial certificates go to: http://www.verisign.com/support/install/intermediate.html For Verisign.com trial certificates go to: http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html For Trustcenter.de go to: http://www.trustcenter.de/certservices/cacerts/en/en.htm#server 对于Thawte.com , 去http://www.thawte.com/certs/trustmap.html下载
&8226; 把Chain Certificate 输入到你的keystore里边
keytool -import -alias root -keystore <your_keystore_filename> /
-trustcacerts -file <filename_of_the_chain_certificate>
&8226; 最后输入你的新的认证书
keytool -import -alias tomcat -keystore <your_keystore_filename> /
-trustcacerts -file <your_certificate_filename>
Troubleshooting
这里是一些你在设置SSL通信时也许会遇到的常见问题,以及如何解决它们。
&8226; 我在我的日志文件中得到"java.security.NoSuchAlgorithmException"错误。
JVM找不到JSSE JAR 文件。按照所有的指导说明 下载并安装JSSE。
&8226; 当Tomcat启动时,我得到一个象 "java.io.FileNotFoundException: {some-directory}/{some-file} not found"的异常。
一个可能的解释是Tomcat不能在它要找的地方找到 keystore文件。在默认的情况下, Tomcat预计 keystore文件在Tomcat运行的用户主目录里被命名为.keystore。 如果 keystore存放在别的什么地方,你需要向Tomcat配置文件里的 <Factory>元素添加一个 keystoreFile属性。
&8226; 当Tomcat启动时,我得到一个象"java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect"的异常。
如果没有其他人 试图 修改你的 keystore 文件,最可能的情况是 Tomcat 用了错误的密码。你可以尝试重新产生 keystore 文件,或修改 Tomcat 设置文件里 <Connector> 元素的 keystorePass 属性,还请记住密码是分大小写的。
Miscellaneous Tips and Bits
你可以用下面的办法获取用户 SSL session 的 ID:
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session");
上面的是大体的介绍,现在简要的说明一下我自己配置成功的过程,
首先进入JDK的安装目录:
C:/Program Files/Java/jdk1.6.0_02/bin
在以上目录下输入如下命令:keytool –genkey –alias tomcat –keyalg RSA –keystore tomcat.keystore
操作完毕后,你会看到当前目录下会多出一个tomcat.keystore这个文件,这个就是生成的密钥文件,
如何让tomcat找到并识别出该文件呢?
修改tomcat里的web.xml,添加如下内容:
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
keystoreFile="C:/Program Files/Java/jdk1.6.0_02/bin/tomcat.keystore"
clientAuth="false" sslProtocol="TLS" />
到此,可以做一个简单的测试,看看你配置后的ssl是否成功,
在IE地址栏里输入:https://localhost:8443......
如果出现证书那就是成功了,就这么简单。
接下来就是如果把此ssl应用到我自己的项目里,应用过程无非也就是在请求我本地项目的路径后,会出示数据证书,来进行验证是否是当前会话的发起者,如果是的话,那么会把当前请求的路径转发给https处理,建立ssl连接,此时你仔细看,会发现你刚才输入的http://locahot:8080/your-project会被处理为https://localhost:8443/your-project 。
在此需要在全局配置一下web.xml,内容是这样(需要验证用户名和密码,我的都为tomcat):
<security-constraint>
<web-resource-collection>
<web-resource-name>Success</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>web-user</role-name>
<role-name>tomcat</role-name>
<role-name>role1</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
如果不需要验证的话,那么配置文件这么加:
<security-constraint>
<web-resource-collection>
<web-resource-name>Success</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: