草庐IT

java - 与Tomcat 7相互认证

coder 2023-08-27 原文

我试图将运行在Tomcat 7中的Java Web服务设置为使用双向(双向)身份验证。无论我做什么,似乎都无法在安全端口上连接服务。

这是我创建证书和 keystore 等的工作:

//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文件中的连接器:
<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文件如下所示:
<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>

在启动时设置以下内容:
-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的客户端证书中。

第一个问题:
当我在Firefox上通过服务(例如-https://my.server.com:8443/test)访问端点时,收到响应“安全连接失败”。 SSL收到的记录超过了最大允许长度。 (错误代码:ssl_error_rx_record_too_long)

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

因此,在某个地方,我显然错过了关键的一块。谁能看到我的错误?

更新:@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文件的开头生成以下内容:
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和本教程:Configuring two-way SSL authentication on Tomcat,这些说明中的大多数都从中被释义。

通常,获得相互认证功能的步骤如下:

  • 为tomcat服务器创建一个证书。客户端必须信任此证书。
  • 为tomcat服务器创建一个 keystore ,并将服务器证书导入其中。
  • 为客户端创建证书。服务器必须信任此证书。
  • 客户端证书导入服务器 keystore
  • 使用正确的连接器XML更新tomcat server.xml文件。

  • 以上步骤在服务器上是必需的。完成后,要设置客户端,请执行以下操作:
  • 将客户端证书从服务器复制到客户端。
  • 与服务器通信时使用客户端证书(此过程随客户端应用程序的性质而变化)。

  • 对于证书配置,我在服务器计算机上执行了以下操作:
    # 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中配置连接器。添加如下所示的连接器元素:
    <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中:
  • “端口”属性可以是您想要的任何属性。
  • “keystoreFile”和“truststoreFile”属性应为完整路径。缺省情况下,Tomcat不在与server.xml相同的目录中。
  • “keystorePass”和“truststorePass”属性应与您在创建tomcat.keystore文件中使用的(密码)值匹配。
  • 必须将“c​​lientAuth”属性 设置为“true”。这就是触发相互认证的原因。

  • 此外,在server.xml中,请确保不要定义了AprLifecycleListner。该侦听器的XML如下所示:
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    

    该元素应删除/注释掉。 AprLifecycleListener的配置方式与上述方法不同,因此无法与这些说明一起使用。

    重新启动tomcat。服务器配置应完成。

    我使用Firefox测试了我的工作,因为添加客户端证书很容易。打开Firefox并尝试在连接器中定义的端口上连接到tomcat服务的端点。
    Ex: https://mytomcatdomain.com:8443/test
    

    执行此操作时,您应该从Firefox得到有关不可信连接的标准警报,因为我们为Tomcat服务器创建了自签名证书。为证书添加一个异常(exception),以便我们的客户端(Firefox)信任我们的服务器(Tomcat)。

    添加异常(exception)后,您应该会收到“安全连接失败”消息。错误代码为“ssl_error_bad_cert_alert”。这确认我们的Tomcat服务器正在从客户端请求身份验证。由于我们尚未将Firefox配置为发送受信任的客户端证书,因此请求失败。

    要配置Firefox,我们需要做更多的魔术:
    // 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文件:
    javac DumpPrivateKey.java
    

    现在,我们将使用这个小工具从上面创建的client.keystore文件中提取 key 。将client.keystore和client.cer文件复制到与DumpPrivateKey类相同的目录中。执行以下命令:
    # 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
    

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

    打开Firefox首选项。单击“证书”选项卡。单击“查看证书”按钮。点击“您的证书”标签。

    单击“导入”按钮,然后浏览到先前创建的“client.p12”文件。应该提示您输入客户端证书的密码。

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

    关于java - 与Tomcat 7相互认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27362588/

    有关java - 与Tomcat 7相互认证的更多相关文章

    1. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    2. java - 从 JRuby 调用 Java 类的问题 - 2

      我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

    3. java - 我的模型类或其他类中应该有逻辑吗 - 2

      我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

    4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

      什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

    5. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

      这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

    6. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

      HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

    7. Tomcat AJP 文件包含漏洞(CVE-2020-1938) - 2

      目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控

    8. 【Java入门】使用Java实现文件夹的遍历 - 2

      遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

    9. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

      我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

    10. java - Ruby 相当于 Java 的 Collections.unmodifiableList 和 Collections.unmodifiableMap - 2

      Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur

    随机推荐