2010-04-21 68 views
20

我使用openssl生成认证密钥。这是我的命令:Java密钥库是否可以导入由OpenSSL生成的密钥对?

openssl genrsa -des3 -out enc_key.pem 1024

我导出为CER文件,然后用java的keytool我导入到Java密钥库(JKS)。

keystore听起来不错。我可以从我的Java应用程序加载密钥库。

问题是,当客户端连接到服务器(在这种情况下是FTP服务器,而不是Web服务器,我使用Apache米娜)时,出现异常:

javax.net.ssl.SSLHandshakeException: SSL handshake failed. at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:433) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$5(DefaultIoFilterChain.java:429)

...

Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source) at javax.net.ssl.SSLEngine.wrap(Unknown Source)

...

Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)

有,我要问的几件事情:

  1. 我用openssl生成的认证密码是什么?我们怎么知道?也许通过命令行openssl xxx?
  2. 我去http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA。我把SSL_RSA_xxx设置为启用密码套件,但仍然无法工作(我把SSL_RSA,因为它使用ssl implisit和genrsa,只是我认为genrsa是生成RSA)。这是对的吗?
  3. 有人知道解决方案吗?
  4. 或者,任何人都知道如何从openssl命令行生成标准密钥库,直到可以在java应用程序中使用(偏离密码)。因为现在我可以从openssl和export keystore java生成认证,但是我不知道我使用的密码是什么以及我在java应用程序中如何使用。注意:如果keystore是直接从java生成的,我可以运行。现在的问题是,如果密钥库由java keytool从认证中生成,如openssl(和其他可能)。

任何帮助将不胜感激!谢谢

回答

45

你为什么使用OpenSSL来生成密钥对?为什么不使用keytool

genrsa工具只是生成一个私钥。你如何创建相应的证书?你如何将私钥导入你的Java密钥库? (我问,因为keytool只能从现有的密钥存储区导入私钥,并且只能从Java 6开始导入。)

我怀疑你的问题是你的密钥存储区不包含密钥项(私钥对应证书)。当您使用keytool列出密钥库内容时,有多少个条目?他们是关键条目还是可信条目?


服务器需要访问私钥才能验证自己。要导入私钥,请使用Java 6的增强keytool

创建密钥,并与OpenSSL的证书后,使用OpenSSL创建一个PKCS#12密钥存储:

openssl pkcs12 -export -in cert.pem -inkey key.pem > server.p12 

那么这个存储转换为Java密钥存储:

keytool -importkeystore -srckeystore server.p12 -destkeystore server.jks -srcstoretype pkcs12 

现在在您的SSL启用服务器中使用server.jks,其中包含证书的私钥。

+0

基本上,我可以运行的应用程序(见我的问题点4)通过Java keytool的(是的,就像你说的,这是正确的,我已经做到了)生成的密钥库。如果我直接从java keytool生成密钥库(jks),然后我的应用程序(FTPS服务器)只使用该密钥库,那么效果很好。没有问题。 你为什么我使用OpenSSL生成密钥对的问题是,因为目前客户有许可认证(VeriSign公司),所以我必须先使用OpenSSL进行测试。顺便说一句,密钥工具可以从证书X509导入(通过执行命令:OpenSSL的REQ -x509 -key key.pem -in req.pem -out cert.pem -days 365) – Jef 2010-04-22 02:29:40

+0

从上方 我有导入所产生的密钥继续openssl到java密钥库(jks),并且java应用程序表示密钥库已经有效(我尝试另一个密钥,java可以验证其有效的密钥库)。 问题是,当我运行经由密钥库(来自OpenSSL的证书由Java keytool的进口产生)的应用程序,该应用抛出上述异常。 密钥库包含一个关键条目(它在httpd的SSL),当我做密钥工具列表,该条目已被信任。我执行此命令: keytool -import -v -trustcacerts -alias服务器别名-file cert.pem -keystore cacerts.jks -keypass x -storepass x – Jef 2010-04-22 02:36:27

+0

@Jef - *否,*这是不正确的,或者你的程序会工作;仅仅是因为你的密钥存储区是有效的*格式*并不意味着它*包含了验证服务器所必需的信息。特别是,您的声明“当我执行keytool列表时,该条目已被信任”,这听起来像是一个信任条目,而不是一个关键条目。 **信任条目将不起作用 - 没有私钥。**应用一些简单的推理:您是否曾给'keytool'一个包含私钥的文件?您希望如何在不提供私钥的情况下执行服务器身份验证? – erickson 2010-04-22 16:48:30