SSL/TLS 服务器配置

Posted on Jun 26, 2006

Secure Sockets Layer (SSL) 和 Transport Layer Security (TLS) 用于在客户端和服务器之间建立加密通信通道.

Java 通过 JSSE(javax.net.ssl) , 提供了对 SSL 和 TLS 的支持. 通过其所提供的一系列 API, 开发者可以像使用普通 Socket 一样使用基于 SSL 或 TLS 的安全套接字, 而不用关心 SSL 和 TLS 协议的细节, 例如握手的流程等等. 这使利用 Java 开发安全的 SSL/TLS 服务器或客户端非常容易.

如何使用 javax.net.ssl, 在网上有很多相关的资料, 这里就不多说了.

下面主要说一说如何配置 SSL/TLS 服务器.

Sun 在 JDK 中提供了一个安全钥匙与证书的管理工具 Keytool. Keytool 把钥匙, 证书以及和与它们相关联的证书链储存到一个 keystore, 默任的实现 keystore 的是一个文件, 它有一个密码保护存储在其中的内容.

配置一个 SSL/TLS 服务器需要以下几步:

假设服务器的域名是: test.server.net

  1. 为服务器的 keystore, 以存储证书等.
    keytool -genkey -alias test.server.net -keyalg RSA -keystore <your_keystore_filename>
    
    执行上面的命令式, 会要求用户输入一些信息, 例如keystore密码, 服务器区域等等, 依照提示输入即可.
  2. 生成一个 Certificate Signing Request (CSR), CSR 是提供给证书颁发机构, 供证书颁发机构依据其中信息生成证书的.
    keytool -certreq -keyalg RSA -alias test.server.net -file certreq.csr -keystore <your_keystore_filename>
    
  3. 将 CSR 提供给证书颁发机构 CA, 等待 CA 颁发证书. 知名的 CA 有 Versign, Thawte 等.
  4. 在 CA 的网站上下载 CA 的根证书.
  5. 导入CA的根证书到 keystore 中
    keytool -import -alias root -keystore <your_keystore_filename> -trustcacerts -file <filename_of_the_root_certificate>
    
  6. 导入 CA 颁发的证书到 keystore, CA 通常不会直接返回一个文件, 而是通过网页或 email 以文本形式提供, 需要用户自己创建一个文件, 再将文本拷入.
    keytool -import -alias test.server.net -keystore <your_keystore_filename> -trustcacerts -file <your_certificate_filename>
    

这样就完成对服务器的配置, 最后为服务器指定这个keystore就可以了.

注意: 一定导入正确的 CA 根证书, 最常见的错误就是没有导入或导入错误的 CA 根证书.

注意: 有些客户端, 在使用 SSL/TLS 时必须通过域名来连接服务器, 不能通过 IP 地址来连接. 其所连接的服务器域名和服务器的证书的颁发对象必须相同. 例 如服务器的域名是 test.server.net, 那么服务器的证书也必须是颁发给 test.server.net 的.

证书颁发机构都会免费提供给用户用于测试的证书和相关的根证书, 这种测试用的证书通常只有 14 天到 30 天不等的有效期.

在 SSLServerSocket 这个类中有一个 setNeedClientAuth 方法, 当这个选项设为 true 时, 客户端和服务器在协商时, 服务器会要求客户端也提供验证信息, 如果客户端不能提供, 服务器就会终止会话.

这需要一些额外的配置, 假设客户端是 alice, 服务器是 server:

  1. 一个客户端的 KeyStore 文件, 该文件中包含了对 alice 的授权:
    keytool -genkey -alias alice -keystore <client_keystore_filename>
    
  2. 一个服务器端的 KeyStore 文件, 该文件中包含了对 server 的授权.
    keytool -genkey -alias server -keystore <server_keystore_filename>
    
  3. 一个名为 clientTrust 的客户端 TrustStore 文件, 该文件中包含了对 server 的授权
    keytool -export -alias server -keystore serverKeys -file server.cer
    keytool -import -alias server -keystore clientTrust -file server.cer
    
    ``
  4. 一个名为 serverTrust 的服务器端 TrustStore 文件, 该文件中包含了对 alice 的授权
    keytool -export -alias alice -keystore clientKeys -file alice.cer
    keytool -import -alias alice -keystore serverTrust -file alice.cer
    

将客户端的证书加入到服务器的 TrustStore 中, 同时将服务器的证书加入到客户端的 TrustStore 中, 使客户端和服务器互相信任.

对于 SIPMethod 来说, 无论是做 client 还是 server, 无论是 listener 还是 connector, listener 和 connector 中的 keystore 都是放自己的证书, listener 中的 truststore 中谁想连到我这就放谁的证书, connector 中的 truststore 中我想连到谁那就放谁的证书.