有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java play framework jvm中的多个信任库

目前,我试图使一个播放应用程序能够与数据库进行SSL加密通信。 我为mysql创建了自签名证书和CA。通常情况下,当我将这个CA添加到JAVA_OPTS中时,我可以使应用程序与db服务器进行加密通信

-Djavax.net.ssl.trustStore=/app/path/conf/truststore

在我的应用程序不尝试通过SSL与其他站点通信之前,一切都进展顺利:

 java.net.ConnectException: General SSLEngine problem to https://api.twitter.com/1/statuses/oembed.json?<meh>
    [...]
    Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    [...]
    Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    [...]
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    [...]

错误很明显:无法检查twitter的ssl证书,因为我的信任库不包含签署twitters证书的CA。IIRC我不能为JVM添加多个“javax.net.ssl.trustStore”参数,因此我必须将CA注入play框架。幸运的是,play framework支持ssl,关于文档,我可以添加多个信任库:https://www.playframework.com/documentation/2.4.x/WsSSL 我为ssl创建了一个配置文件:

play.ws.ssl {
  trustManager = {
      stores = [
        { path: /path/to/truststore, type: "JKS", password = "<whatever is it" }
        { path: ${java.home}/lib/security/cacerts } # Default trust store
      ]
  }

但当我启动服务器时,我收到以下错误消息:

Oops, cannot start the server.
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

现在,我被困住了。我可以为JVM注入我的truststore,但当我这样做时,应用程序无法与其他启用SSL的主机通信-没有证书,但当我尝试添加我的truststore for play framework时,它不接受它,因为没有人签署我的证书。 有办法解决这个问题吗?我怀疑如果我使用系统范围的cacert文件(java使用)和我的信任库,然后我将它们与keytool合并,这将解决这个问题,但这不是最好的方法-如果我可以将我的自签名证书打包到应用程序旁边,这将更加明智


共 (3) 个答案

  1. # 1 楼答案

    这个错误意味着Play找不到商店。这条路对吗

  2. # 2 楼答案

    由于某种原因,我自己的信任存储无法被识别,因此我最终将证书添加到默认密钥库(${java.home}/lib/security/cacerts)。您可以使用此命令执行此操作(顺便说一句,cacerts默认密码为changeit): keytool -v -importkeystore -srckeystore alice.p12 -srcstoretype PKCS12 -destkeystore "c:\Program Files\Java\jre1.8.0_71\lib\security\cacerts" -deststoretype JKS 然后需要定义信任管理器和密钥管理器。trustManager指向信任存储,keyManager指向您的证书

    play.ws.ssl {
      trustManager = {
        stores = [
          {
            path: ${java.home}/lib/security/cacerts 
          }
        ]
      }
      keyManager = {
        stores = [
          {
            type: "PKCS12",
            path: "/Users/work/Documents/path/to/certificate/certificate.p12",
            password: "pass"
          }
        ]
      }
    }
    
  3. # 3 楼答案

    我收到了相同的错误消息:java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty由空存储区引起。根据Key store docs,配置中可能有password字段,但它被忽略,因此未从存储中读取证书。我必须使用PEM格式,或者您可以在配置中包含证书,请参见Configure store。密码字段被添加/放回commit #e867e729。我在玩2.6,所以我不能测试它