游戏框架中的多个信任库 - jvm

时间:2016-05-05 13:09:08

标签: java ssl https playframework jvm

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

-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我不能添加多个&#34; javax.net.ssl.trustStore&#34; JVM的参数,所以我必须将我的CA注入play框架。为了好运,play框架支持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注入我的信任库,但是当我这样做时,应用程序无法与其他启用SSL的主机通信 - 没有证书,但是当我尝试为play框架添加我的信任库时,它不接受它,因为没有人签署我的证书。 有办法以某种方式解决这个问题吗?我怀疑如果我采用系统范围的cacert文件(由java使用)和我的信任库,然后我将它们与keytool合并,它将解决这个问题,但这不是最好的方法 - 如果我能做的话会更加理智在应用程序旁边打包我自己签名的证书。

3 个答案:

答案 0 :(得分:0)

该错误表示Play无法找到商店。路径是否正确?

答案 1 :(得分:0)

由于某些原因,我遇到了同样的问题,我的信任存储不会被识别,因此我最终将我的证书添加到默认密钥库($ {java.home} / lib / security / cacerts)。您可以使用此命令执行此操作(BTW 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和密钥管理器。 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"
      }
    ]
  }
}

答案 2 :(得分:0)

我有相同的错误消息:java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty由空存储引起。根据{{​​3}},配置中可能存在password字段,但是该字段被忽略,因此不会从存储中读取证书。我必须使用PEM格式,或者可以在配置中包含证书,请参见Key store docs。密码字段已添加/放回Configure store。我使用的是Play 2.6,因此无法对其进行测试。