Import client self signed cert into java keystore - java

See also: Can a Java key store import a key pair generated by OpenSSL?
I am provided with the following files to authenticate against a thrift endpoint:
cacert.pem
local.crt
local.key
I am having the hardest time trying to create a keystore that has the client cert in it. The endpoint application has its own CA to authenticate they client certs. I honestly am not sure what needs to be included in the keystore (assuming the client cert, and the endpoint public cert), but for the life of me can not get it working.
Does anyone know how to import a client cert into a keystore? Or, what I need to do in order to get this working? Thanks.

The problem was with the keystore, this is how I finally got it working.
First thing to note is that its not possible (as far as I know) to import private keys into a keystore using keytool...
Knowing that, I converted the local.crt and local.key to a .p12 file via openssl:
openssl pkcs12 -export -in local.crt -inkey local.key -out local.p12
Then used a tool from IBM (keyman): http://www.alphaworks.ibm.com/tech/keyman/download
To import the CA cert (cacert.crt) and then the .p12 file, then saved that as a keystore.
Hope this helps someone!

Related

Convert PKCS7 to PKCS12 using java.security.KeyStore

When I try to import a renewed X509 certificate on Chrome / Firefox (and probably other browser), it does not recognize that the certificate I am trying to import uses the same private key stored in my expiring user certificate with the same DN. I don't know if this is a bug with the implementation of certificate import tool of all major browsers, but I can (somewhat) work around this problem by storing my user certificate inside a private key-less PKCS12 file using openssl tool like following.
openssl pkcs12 -export -in usercert.pem -nokeys -name "CN: Same Name" -out certonly.p12
(-nokeys is the trick here)
I don't know why this works, but I can then import certonly.p12 to Chrome / Firefox and it will attach my private key from the last year; although it creates a separate certificate entry so that I need to remove my old certificate manually.
So, I assume that, in order to renew my user certificate on my browser, I will need to package my certificate in PKCS12 format (with or without a pass-phrase).
Now, I need to do this in my Java application using java.security.KeyStore or similar libraries, because it is actually my web application which is generating user's renewed certificates. I don't want to ask our users to use the openssl command themselve to convert it to pkcs12 before importing to their browsers. My application should do this automatically, and provide them the renewed certificate contained inside a PKCS12 file.
I've looked many places, but so far I can't find a concrete example of how to do this using Java. Does anyone know how to output a pass-phrase less PKCS12 with only an issued certificate (or pkcs7) without a private key?
I tried something like following but it did not work.
java.security.cert.Certificate[] chain = CertificateManager.parsePKCS7(renewed_cert_in_pkcs7);
KeyStore p12 = KeyStore.getInstance("PKCS12");
p12.load(null, null);
p12.setKeyEntry("USER Cert 123", null, "".toCharArray(), chain);
response.setContentType("application/x-pkcs12");
response.setHeader("Content-Disposition", "attachment; filename=user_certificate_only.p12");
p12.store(response.getOutputStream(), "".toCharArray());

how to get and SSL CA into Java server

So this may be a stupid question but I have been scouring the internet all day trying to figure out how to get a trusted SSL certificate into my java server.
Details:
I created a java server that creates an SSLServerSocket accepts connections. I used keytool to create a keystore called domain.key as well as a certificate request (csr). I then contacted a certificate authority (starfield) and gave them my csr, they did their thing and returned to me the certificates (crt). I have 3 of them. one is called domain.com.crt, one is called sf_bundle.crt, and one is called sf_intermediate.crt
After much searching I found that I need to import the certificates into a keystore and that the keystore can be the same one that has my public/private keys or it can be in a seperate file. I chose to put it into a seperate file called domain.trust.
I then modified my server to import the trust store as well as the keystore using:
System.setProperty("javax.net.ssl.keyStore", "domain.key");
System.setProperty("javax.net.ssl.trustStore", "domain.trust");
along the corresponding lines for the keystore password and the truststore password.
The problem is that when i try and connect using any client it always says that the certificate is sell signed.
I have been using http://certlogik.com/ssl-checker/ to test it.
I obviously have missed a step but I cant find out where.
Any help would be greatly appreciated
The problem is that when i try and connect using any client it always
says that the certificate is sell signed.
This indicates that the root CA certificate is being send to the client.
You don't mention how you created this separate keystore you use.
You should be doing something like the following:
keystore.setKeyEntry("alias", privateKey, password, chain);
And chain would have:
chain[0] --> Your server's certificate
chain[1] --> The signer's certificate
....
chain[N] --> Signer up to the root
You first need to understand what happens during an SSL Handshake. Maybe then you can narrow down the problem. You can refer to various docs on internet., http://www.pierobon.org/ssl/ch/detail.htm
Your running server must have either have the CA StarField installed in it. Or it should have a trust relationship with the CA StarField.
You rclient certificate must be CSR signed by CA StarField, which I guess you have already done.
Now when you present your certificate to the Server, it checks with the CA's it has.
So, if the Sever has the CA StarField and your certificate is signed by StarField then there is no way you would get the Self Signed error.
You get that only when your certificate is not signed by the CA. Just open your certificate and check it's Issuer details to confirm.
Firstly, you seem to be confused about the difference between keystore and truststore. This answer may be of interest.
Essentially, unless you want to use client-certificate authentication, you have no need to change the trust store, from a server point of view.
After much searching I found that I need to import the certificates
into a keystore and that the keystore can be the same one that has my
public/private keys or it can be in a seperate file.
To be able to use the certificate you got from the CSR you initially had, you MUST import that certificate back in the keystore with which you generated the CSR, and you MUST import it, along with the whole certificate chain, into the correct alias, where the private key is stored.
This is essentially the same problem as the one in this question, but from the server side here.
Find the alias name that has your private key using keytool -list -keystore store.jks:
Your keystore contains 1 entry
myalias, Feb 15, 2012, PrivateKeyEntry,
Certificate fingerprint (MD5): xxxxxxxx
The prepare a bundle with your certificate and the chain of CA certificates in the right order (your own certificate first, and then each issuer one by one):
-----BEGIN CERTIFICATE-----
MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----
(You can verify the content of each certificate using openssl x509 -text -noout and pasting each ---BEGIN/END--- block, including delimiters into its standard input.)
Then, import that file in a single step:
keytool -importcert -keystore store.jks -alias myalias -file bundle.pem

Sending POST request to a server that uses a self signed certificate

I need to send a POST request to a server that uses some levels of security. Unfortunately I don't know much about self signed certificates, I never used or studied it.
In the developer guide of the service it sais that the server uses a "public 1024-bit self signed certificate".
What does it mean? I've to create a certificate or I've to ask for it?
If i've to create a certificate, then how I should use it?
I'm implementing the client in Java
You need to download the certificate e.g. with your internet browser. Click through the security information and export the certificate.
Then you need to import it into your local java keystore so that the JVM can find it. For import use the keytool which you find in your jre/bin directory. Documentation for the keytool: http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/keytool.html
The default keystore is jre/lib/security/cacerts.
Then you can import the downloaded certificate:
jre/bin/keytool -import -keystore jre/lib/security/cacerts -alias mycertificate -file downloads/mycertificate.cer
Hope this helps.
P.S. If it is self signed or verified its not important at this point. Just you (your client) must trust it.

Creating an SSL Connection in Java

I looked around and did not see any questions that fully answered what I wanted, though if this is a duplicate, point me to the question and I will be on my way.
Right now I am trying to write a Java server that will receive data from an SSLServerSocket and for now, just print it out. I would eventually like to have this data come from an Android, but right now it throws an SSLException before it even starts listening for data.
code:
System.setProperty("javax.net.ssl.keyStore","C:\\ProgramFiles\\jre6\\bin\\server.jks");
System.setProperty("javax.net.ssl.keyStorePassword","password");
SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket ss = factory.createServerSocket(6543);
Socket s = ss.accept();
There is more code after that to process it, but it gets hung up and throws the exception there, so I'm not sure posting it will help any, but if it will, just comment for it.
I created the certificate following a tutorial for openssl on Ubuntu and transferred it over and created my keystore using:
keytool -import -file "C:\Documents and Settings\matt\Desktop\server.crt" -keystore server.jks
I can easily admit that I don't fully understand how a large portion of this works, so any help would be appreciated. Also, I suppose I am going to leave it outside the scope of this question becauseI feel like this is a pretty big question on its own, butI would also like some insight as to how to connect the client if possible. Sorry for all the trouble and thanks ahead of time for all the help.
EDIT:
the tutorial I followed is here:
http://www.akadia.com/services/ssh_test_certificate.html
Thanks again!
EDIT:
The Exception being throw is:
javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled
I tried to Google the exception and most everything was a tutorial describing how to create a keystore (which I am under the impression that I already have). I will continue to sift through these search results.
Thanks!
When you create a keystore like this, you only put a certificate in your keystore:
keytool -import -file "server.crt" -keystore server.jks
What you need is to have a private key + a certificate.
Either you import them from somewhere else if you already have a certificate issued by a Certification Authority, or you can create a self-signed certificate if it's for limited use.
If the certificate you've created with OpenSSL is self-signed (or from a mini CA for your own use, e.g. with CA.pl), it's probably not worth the trouble of doing the conversion. You might as well generate a self-signed certificate directly with keytool. See the "Generating Your Key Pair" example in the official keytool documentation:
keytool -genkeypair -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US"
-alias business -keypass kpi135 -keystore /working/mykeystore
-storepass ab987c -validity 180
Make sure you use cn=your.fqdn.host.name (or cn=localhost if it's for local tests only). (I think keytool provided with Java 7 also has support for subject alternative names, which would be better.)
If you already have a private key + certificate you want to re-use in PKCS#12 format (usually .p12 file), you can import it using the method described in this question.
If what you've produced with OpenSSL is in PEM format, it might be easier to bundle them in a PKCS#12 file with OpenSSL and then import them as above. This can be done with this:
openssl pkcs12 -export -in cert.pem -inkey key.pem -out creds.p12

Java Sign jars with server certificate

Is it possible to use a server certificate to sign a java web start app? What I want to know is if will it work. I have a trusted certificate for my server, and I would like to reuse the same certificate to sign an app.
Right now, I have this warning:
This jar contains entries whose signer certificate's ExtendedKeyUsage
extension doesn't allow code signing. This jar contains entries whose
signer certificate's NetscapeCertType extension doesn't allow code
signing.
Will I be able to launch my app without the warning that the certificate is not trusted?
You will get warning if you don't use a code signing certificate. For most CA, code signing cert costs more than the server cert. In my opinion, this is just a marketing scheme to make you to pay for another cert. There is no technical difference between two certs. Some CA may provide combo deals with usage for both.
I assume you have created the JKS file using the KEY and CRT of your SSL and hence you get the error..
I have a simple solution here:
As you know you can create a JKS using the following command
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
and when you use this JKS you get self signed certification message which is absolutely fine to make the app live at Google play store.. But buying code signing certificate is good if you can afford it ..

Categories

Resources