与Tomcat 7的相互身份验证 [英] Mutual authentication with Tomcat 7

查看:148
本文介绍了与Tomcat 7的相互身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置在Tomcat 7中运行的Java Web服务以使用相互(双向)身份验证。似乎无论我做什么,连接到安全端口上的服务都无法正常工作。

I'm trying to set up a Java web service running in Tomcat 7 to use mutual (2-way) authentication. It seems like no matter what I do, connecting to the service on the secure port isn't working.

以下是我创建证书和密钥库所做的事情:

Here's what I did to create certificates and keystores and such:

//create the key and certificate for the tomcat server.
keytool -genkey -v -alias tomcat -keyalg RSA -validity 3650 -keystore tomcat.keystore

//create the key and certificate for the client machine.
keytool -genkey -v -alias clientkey -keyalg RSA -storetype PKCS12 -keystore client.p12

//export the client key
keytool -export -alias clientkey -keystore client.p12 -storetype PKCS12 -rfc -file client.cer

//import the client key into the server keystore
keytool -import -v -file client.cer -keystore tomcat.keystore

这是server.xml文件中的连接符:

Here's the connector in the server.xml file:

<Connector port="8443"
    maxThreads="150"
    scheme="https"
    secure="true"
    sslProtocol="TLS"
    clientAuth="true"
    keystoreFile="tomcat.keystore"
    keystorePass="tomcat"
    truststoreFile="tomcat.keystore"
    truststorePass="tomcat"/>

tomcat-users.xml文件如下所示:

The tomcat-users.xml file looks like this:

<tomcat-users>
    <role rolename="tomcat"/>
    <role rolename="admin"/>
    <!-- note that the actual values for CN, OU, O, L, ST are different, but they match the values created in the client certificate -->
    <user username="CN=name, OU=unit, O=org, L=locality, ST=state, C=US" password="null" roles="admin" />
</tomcat-users>

以下是在启动时设置的:

The following are set on startup:

-Djavax.net.ssl.keyStoreType=jks
-Djavax.net.ssl.keyStore=tomcat.keystore
-Djavax.net.ssl.keyStorePassword=tomcat
-Djavax.net.ssl.trustStore=tomcat.keystore
-Djavax.net.ssl.trustStorePassword=tomcat
-Djavax.net.debug=SSL

最后,我将client.p12文件复制到我的客户端计算机,并将其导入Firefox的客户端证书。

Finally, I copied the client.p12 file to my client machine, and imported it into Firefox's client certificates.

第一个问题:
当我点击我的服务端点时(例如 - https://来自Firefox的my.server.com:8443/test )我收到安全连接失败的回复。 SSL收到的记录超过了允许的最大长度。 (错误代码:ssl_error_rx_record_too_long)

First problem: When I hit an endpoint on my service (example - https://my.server.com:8443/test) from Firefox, I get the response "Secure Connection Failed". SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long)

第二个问题:
我真的不想在端口8443上运行此连接器。我想在端口7800上运行它(这是我们公司的HTTPS标准)。当我将连接器上的端口更改为7800并尝试命中端点时(例如 - https://my.server.com:7800 / test )然后它永远不会解析页面。

Second problem: I don't really want to run this connector on port 8443. I want to run it on port 7800 (which is our company standard for HTTPS). When I change the port on the Connector to 7800 and try to hit the endpoint (example - https://my.server.com:7800/test) then it never resolves the page.

所以,在某个地方,我显然错过了一个关键的部分。任何人都可以看到我的错误吗?

So, somewhere I'm obviously missing a crucial piece. Can anyone see my error?

更新:来自@Dave G的反馈

UPDATE: after feedback from @Dave G

运行命令:

openssl s_client -connect localhost:8443 -showcerts

产生以下输出:

CONNECTED(00000003)
140642290976584:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:766:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 263 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

我还在启动时添加了-Djavax.net.debug = SSL。这会在catalina.out文件的开头生成以下内容:

I also added -Djavax.net.debug=SSL to the startup. This generates the following in the beginning of the catalina.out file:

trustStore is: tomcat.keystore
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
  Subject: CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Issuer:  CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Algorithm: RSA; Serial number: 0x5485b5a5
  Valid from Mon Dec 08 14:28:53 UTC 2014 until Thu Dec 05 14:28:53 UTC 2024

adding as trusted cert:
  Subject: CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Issuer:  CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Algorithm: RSA; Serial number: 0x5485b6af
  Valid from Mon Dec 08 14:33:19 UTC 2014 until Sun Mar 08 14:33:19 UTC 2015

trigger seeding of SecureRandom
done seeding SecureRandom

然后很多:

Ignoring unavailable cipher suite: <suite name>
Ignoring unsupported cipher suite: <suite name>


推荐答案

好的 - 经过深入挖掘后,我终于得到了这工作。非常感谢@Dave G和本教程:在Tomcat上配置双向SSL身份验证,其中大部分说明都是转发的。

Ok - after digging a lot more, I finally got this working. Much thanks to @Dave G and this tutorial: Configuring two-way SSL authentication on Tomcat from which most of these instructions are paraphrased.

一般来说,步骤获得相互身份验证功能如下:

Generally, the steps to get mutual authentication functional are as follows:


  1. 为tomcat服务器创建证书。客户端必须信任此证书。

  2. 为tomcat服务器创建密钥库,并将服务器证书导入其中。

  3. 为其创建证书客户端。服务器必须信任此证书。

  4. 客户端证书导入服务器密钥库

  5. 使用正确的Connector XML更新tomcat server.xml文件。

  1. Create a certificate for the tomcat server. The client has to trust this certificate.
  2. Create a keystore for the tomcat server, and import the server certificate into it.
  3. Create a certificate for the client. The server has to trust this certificate.
  4. Import the client certificate into the server keystore
  5. Update the tomcat server.xml file with the correct Connector XML.

上述步骤在服务器上是必需的。完成后,要设置客户端,请执行以下操作:

The above steps are necessary on the server. Once completed, to set up the client, do the following:


  1. 将客户端证书从服务器复制到客户端。

  2. 与服务器通信时使用客户端证书(此过程因客户端应用程序的性质而异)。

对于证书配置,我在服务器计算机上执行了以下操作:

For the certificate configuration, I executed the following on the server machine:

# For the following commands, set the values in parenthesis to be whatever makes sense for your environment.  The parenthesis are not necessary for the command.

# This is an all-in-one command that generates a certificate for the server and places it in a keystore file, while setting both the certifcate password and the keystore password.
# The net result is a file called "tomcat.keystore". 

keytool -genkeypair -alias (serveralias) -keyalg RSA -dname "CN=(server-fqdn),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keystore tomcat.keystore -keypass (password) -storepass (password)

# This is the all-in-one command that generates the certificate for the client and places it in a keystore file, while setting both the certificate password and the keystore password.
# The net result is a file called "client.keystore"

keytool -genkeypair -alias (clientalias) -keyalg RSA -dname "CN=(client),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keypass (password) -keystore client.keystore -storepass (password) 

# This command exports the client certificate.  
# The net result is a file called "client.cer" in your home directory.

keytool -exportcert -rfc -alias (clientalias) -file client.cer -keypass (password) -keystore client.keystore -storepass (password)

# This command imports the client certificate into the "tomcat.keystore" file.

keytool -importcert -alias (clientalias) -file client.cer -keystore tomcat.keystore -storepass (password) -noprompt

现在应该适当地设置证书。下一步是在tomcat server.xml中配置连接器。添加如下所示的连接器元素:

Certificates should now be set up appropriately. The next step is to configure your connector in the tomcat server.xml. Add a connector element that looks like this:

<Connector port="8443"
    maxThreads="150"
    scheme="https"
    secure="true"
    SSLEnabled="true"
    truststoreFile="/full/path/to/tomcat.keystore"
    truststorePass="(password)"
    keystoreFile="/full/path/to/tomcat.keystore"
    keystorePass="(password)"
    clientAuth="true"
    keyAlias="serverkey"
    sslProtocol="TLS"/>      

请注意,在上面的XML中:

Note that in the above XML:


  1. port属性可以是您想要的任何内容。

  2. keystoreFile和truststoreFile属性应该是完整路径。默认情况下,Tomcat与server.xml不在同一目录中。

  3. keystorePass和truststorePass属性应与您在创建tomcat时使用的(密码)值相匹配.keystore文件。

  4. clientAuth属性必须设置为true。这就是触发相互身份验证的原因。

  1. The "port" attribute can be whatever you want.
  2. The "keystoreFile" and "truststoreFile" attributes should be full paths. Tomcat does not look in the same directory as server.xml by default.
  3. The "keystorePass" and "truststorePass" attributes should match the (password) value you used in the creation of the tomcat.keystore file.
  4. The "clientAuth" attribute must be set to "true". This is what triggers mutual authentication.

此外,在server.xml中,确保不要定义了一个AprLifecycleListner。该侦听器的XML将如下所示:

Additionally, in the server.xml, ensure that you DO NOT have an AprLifecycleListner defined. The XML for that listener will look something like this:

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

该元素应删除/注释掉。 AprLifecycleListener的配置方式与上述相同,不适用于这些说明。

That element should be delete/commented out. The AprLifecycleListener does not get configured the same way as described above, and will not work with these instructions.

重启tomcat。服务器配置应该是完整的。

Restart tomcat. The server configuration should be complete.

我使用Firefox测试了我的工作,因为很容易为它添加客户端证书。打开Firefox并尝试连接到连接器中定义的端口上的tomcat服务端点。

I tested my work using Firefox, because it's easy to add client certificates to it. Open up Firefox and try to connect to an endpoint of your tomcat service on the port defined in your connector.

Ex: https://mytomcatdomain.com:8443/test

执行此操作时,您应该从中获取标准警报Firefox关于不受信任的连接,因为我们为Tomcat服务器创建了自签名证书。添加证书的例外,以便我们的客户端(Firefox)信任我们的服务器(Tomcat)。

When you do this, you should get the standard alert from Firefox about an untrusted connection because we created a self-signed certificate for our Tomcat server. Add an exception for the certificate so that our client (Firefox) trusts our server (Tomcat).

添加例外后,您应该获得安全连接失败的消息。错误代码是ssl_error_bad_cert_alert。这确认我们的Tomcat服务器正在请求来自客户端的身份验证。请求失败,因为我们尚未将Firefox配置为发送我们的可信客户端证书。

Once you've added the exception, you should get a "Secure Connection Failed" message. The error code is "ssl_error_bad_cert_alert". This confirms that our Tomcat server is requesting authentication from the client. The request is failing because we have not configured Firefox to send our trusted client certificate yet.

要配置Firefox,我们需要做更多的魔术:

To configure Firefox, we need to do a little more magic:

// Create a file called DumpPrivateKey.java.  The contents should look like so:
public class DumpPrivateKey {
public static void main(String[] args) throws Exception {
  final String keystoreName = args[0];
    final String keystorePassword = args[1];
    final String alias = args[2];
    java.security.KeyStore ks = java.security.KeyStore.getInstance("jks");
    ks.load(new java.io.FileInputStream(keystoreName), keystorePassword.toCharArray());
    System.out.println("-----BEGIN PRIVATE KEY-----");
    System.out.println(new sun.misc.BASE64Encoder().encode(ks.getKey(alias, keystorePassword.toCharArray()).getEncoded()));
    System.out.println("-----END PRIVATE KEY-----");
  }
}

使用以下命令编译java文件:

Compile the java file with the following command:

javac DumpPrivateKey.java

现在我们将使用这个小实用程序从我们上面创建的client.keystore文件中提取密钥。将client.keystore和client.cer文件复制到与DumpPrivateKey类相同的目录中。执行以下命令:

Now we're going to use this little utility to extract a key from the client.keystore file we create above. Copy the client.keystore and client.cer files into the same directory as your DumpPrivateKey class. Execute the following:

# This extracts the client key from the client keystore

java DumpPrivateKey client.keystore (password) clientkey > clientkey.pkcs8

# This creates a client.p12 file that can be used by Firefox

openssl pkcs12 -export -in client.cer -inkey clientkey.pkcs8 -password pass:(password) -out client.p12

请注意,在上面的代码中,(密码)应该是用于创建client.keystore的密码。

Note that in the above code, (password) should be the password you used to create the client.keystore.

打开Firefox首选项。单击证书选项卡。单击查看证书按钮。单击您的证书选项卡。

Open up Firefox preferences. Click on the "Certificates" tab. Click on the "View Certificates" button. Click on the "Your Certificates" tab.

单击导入按钮并浏览到先前创建的client.p12文件。系统将提示您输入客户端证书的密码。

Click on the "Import" button and browse to the "client.p12" file that was created previously. You should be prompted to enter the password for the client certificate.

假设client.p12已成功导入,您现在可以刷新Firefox页面,您应该从Tomcat服务器端点获得成功响应。

Assuming the "client.p12" was imported successfully, you can now refresh you Firefox page, and you should get a successful response from your Tomcat server endpoint.

这篇关于与Tomcat 7的相互身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆