views:

1208

answers:

1

I generate a certification key with openssl. Here is my command:

openssl genrsa -des3 -out enc_key.pem 1024

I export into cer file, then with java keytool I import into java keystore (jks).

The keystore sounds good. I can load the keystore from my java app.

The problem is when client connect to the server (In this case is FTP server, not web server, and I use apache mina), the exception occured:

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)

There is a few things that I want to ask:

  1. What is the cipher of certification that I generate with openssl? How can we know? maybe by command line openssl xxx?
  2. I go to http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA. And I put SSL_RSA_xxx to enabled cipher suites, but still can't work (I put SSL_RSA because it the SSL is using ssl implisit, and genrsa, just my opinion genrsa is generate RSA). Is it correct?
  3. Anybody knows the solution?
  4. Or, anybody knows how to generate the standard keystore from openssl command line until can be used in java app (off course with the cipher). Because right now I can generate the certification from openssl and export keystore java, but I don't know what is the cipher that I used and how I use in the java app. Note: I can run if the keystore is generate directly FROM java. Right now the problem is if the keystore generated by java keytool from certification like openssl (and other maybe).

Any help will be appreciated! Thanks

+1  A: 

Why are you using OpenSSL to generate the keypair? Why not just use keytool?

The genrsa tool just generates a private key. How are you creating a corresponding certificate? How are you importing the private key into your Java keystore? (I ask, because keytool can only import a private key from an existing key store, and only from Java 6 onward.)

I suspect that your problem is that your key store doesn't contain a key entry (private key and corresponding certificate). When you list the keystore contents with keytool, how many entries are there? Are they key entries or trusted entries?


The server needs access to the private key in order to authenticate itself. To import a private key, use Java 6's enhanced keytool.

After creating the key and the certificate with OpenSSL, use OpenSSL to create a PKCS #12 key store:

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

Then convert this store into a Java key store:

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

Now use server.jks in your SSL-enable server, which contains the certificate and the private key.

erickson
Basically, I can run the app (see my question point 4) with keystore that generated by java keytool (yes, like you said, it's correct, I already did it). It works well if I generate directly keystore (jks) from java keytool then my app (FTPS server) just use that keystore. No problem with that.Your question why I using OpenSSL to generate the keypair is because currently the client has license certification (verisign) so I have to test with openssl first. Btw, keytool can import from cert x509 (by doing command: openssl req -x509 -key key.pem -in req.pem -out cert.pem -days 365)
Jef
Continue from aboveI have import the key that generated by openssl to java keystore (jks) and the java app said the keystore is already valid (i try the other key, java can verify its valid keystore or not).The problem is when I run the app via keystore (generated by java keytool import from openssl cert), the app throws Exception above.The keystore is contain a key entry (it works in httpd ssl), when I do keytool list, the entry is already trusted. I do this command:keytool -import -v -trustcacerts -alias server-alias -file cert.pem -keystore cacerts.jks -keypass x -storepass x
Jef
@Jef — *No,* it's not correct, or your program would work; just because your key store is in a valid *format* doesn't mean it *contains* the information necessary to authenticate the server. In particular, your statement, "when I do a keytool list, the entry is already trusted," makes it sound like it's a trust entry, not a key entry. **A trust entry will not work—there's no private key.** Apply some simple reasoning: do you ever give `keytool` a file containing the private key? How do you expect to perform server authentication without making the private key available?
erickson
Jef
To generate jks that used in app (ftps apache mina), i use this: keytool -import -v -trustcacerts -alias server-alias -file cert.pem -keystore cacerts.jks -keypass password -storepass password. the cacert.jks I use in the app, if the password is same, it works, if not it throws exception, said bad password etc. So I think the app is already 'received' the jks, right? If the condition like that, if you said need private key available to perform server authentication, when I do ftps connection (implisit SSL) for example use filezilla, how I can browse the private key to authenticate ftps? thx
Jef
@Jef — You are trying to produce a key store for the server, right? The server always needs a private key. Anyone can get the certificate; it's public. But without the private key, they couldn't impersonate the server. Following the steps above, the private key ("key.pem") that goes together with "cert.pem" is never imported to the Java key store. If you use Java 6, you can "import" a PKCS #12 key store (including private keys) created by OpenSSL into a "JKS" Java key store. Otherwise, it won't work.
erickson
sorry, erickson... seems like I more understand what your mean. I have do: openssl pkcs12 -export -in cert.pem -inkey key.pem > server.p12, and it works. but when I do: keytool -importkeystore -srckeystore server.p12 -destkeystore server.jks -srcstoretype pkcs12, seems like the command is invalid. Maybe the valid command is: keytool -import -file server.p12 -keystore server.jks -storetype pkcs12, is it correct? If yes, when I do that, the result is: keytool error: java.lang.Exception: Input not an X.509 certificate.
Jef
@Jef — To make this work, you have to use **Java 6**. Previous versions do not have the import key store feature. You don't have to run or develop your program with Java 6, but unless you write some of your own code to manage the key store, you will need a Java 6 runtime to convert the key store.
erickson
Ok erickson, it works. Thanks! java 5 can't do that. java 6 CAN do that (your commands above). For alternative (maybe you already know this too), I have tried with to convert in java 5 with this guide: http://www.agentbob.info/agentbob/79-AB.html
Jef