SSL Certificate X.509 Export - java

I'm trying to use a Web Service but I have many doubts about the certificates, I'm quite a novice in this topic, The team that developed the web services sent me a document where explains how to use it but to enable the connection, I need to USE a certificate (X.509), I generated p7b certificate from they website and I imported that certificate in my local environment, Using Keytool -import it generate a JKS file but they warn that I should install "Entrust" (Root and Intermediate) certificates that they provide me I used keytool -import with these .cer files and the command generated one .JKS for each file, I installed those cer too, my question is:
To use that web service Which certificate file I need to attach in my implementation logic in java, the jks or p7b ?
How I can use this certificate in all the Test environment? (I don't know if this certificate can be use only in the PC that generates the CSR).
I'm trying to simulate the call with the SOAPUI app i'm getting the authentication error so Probably something is worng with the certificate.
He implemented all using windows certificate store and .NET they can't give me support for keytool.

To do client authentication (also called mutual authentication) in SSL/TLS you (your program) needs not just a certificate but a certificate PLUS PRIVATE KEY and usually intermediate/chain certs. There are canonically 5 steps in the process:
On your computer generate a key PAIR which consists of a privatekey and a publickey, and a Certificate Signing Request (CSR) which contains the publickey. These steps may be done separately, or combined in a way that you don't notice there are both a CSR and a privatekey.
Submit the CSR to a Certificate Authority (CA) along with evidence of your identity and authorization as appropriate, and payment if the CA requres it.
The CA issues an 'end-entity' certificate (in this case a client cert) containing your publickey and identity(ies) plus some other information and gives you this certificate, usually along with an intermediate certificate or sometimes a few intermediate certs that form(s) a 'chain' from the entity cert to a trusted CA root or anchor cert. A 'p7b' file is one fairly common way, though not the only one, of transporting a group of related certs, such as your entity cert plus your chain cert(s).
You return the entity cert and the chain cert(s) to your computer and combine with your privatekey from step 1.
You use the combination of privatekey PLUS certificate chain with various program(s) such as a browser, a utility like curl, or a custom application.
Details of steps 1 and 4 (and 5) depend on the systems and software you use, which you don't specify in any recognizable way, although it sounds like you are ending up in the Windows certificate store. If that is the case, and it is specifically the Personal section of the current-user store (as opposed to a machine account like SYSTEM), then when you run MMC (aka Administrative Tools) and select the Cert Mgr addin, or directly run certmgr.msc, the icon for the cert should have a yellow key at the left:
Contrary to your Q, Java JCE (at least Oracle-was-Sun Java on Windows) can handle this; run keytool -list -storetype Windows-MY -keystore NONE and see for yourself.
However, some (probably many) Java programs cannot. For those, you need a keystore file containing the privatekey PLUS certificates; to create that run the Export wizard and select 'Yes, export private key', then format PKCS 12 (aka PFX) with 'include ... path'.
Recent updates of Java 8 by default can automatically handle a PKCS12 keystore (look for keystore.type.compat=true in JRE/lib/security/java.security) and older versions can do so if the program configures the store type (I don't know if SoapUI does that). For older versions that require JKS, after exporting to PKCS12 to let's say mykey.p12 convert with
keytool -importkeystore -srcstoretype pkcs12 -srckeystore mykey.p12 -destkeystore mykey.jks

What you try to archivee is something called a mutual-authentication. In order to understand the basics you need to understand that the humans have simply concepted a password to lock and unlock informations by the same (symetric) password. Everyone who knows the one password can
read the message
rewrite the message to send false informations
this is dangerous. So they have invented two different passwords, one for writing (private) and a compleatly different one for receive(public), we call them asymetric. The problem in asymetric encryption was, that you can choose free only one password, the opposite password is calculated and can not be choosen freely.
Finally they invented certificates to simplify the process. Certificates contains strong Passwords packed into files. Without looking into the certificates you dont know if the passwords are private or public, that means p7b(pkcsv7b) and jks can contain the absolute same informations. The difference is the format only, like the difference between .doc and .docx.
The second problem
In the big japaneese war's spionage was a big thing, the agents gathered informations about the opposite at the point of tactics and send theese informations to their real lords to find weaknesses in the tactics/strategys. Whenever a spoin has been uncovered he has been turned into a double-agent faking honeypots to let the warlord make wrong decisions and fall into traps.
So as an warlord you must trust your agent ... but, how to be sure? Well, you can ask the other agents about the agent you have the informations from to have the guarantee that the message can be trusted. So the first agent must ask other agents to sign the message too, this question between agents is the CSR! If the other agent(s) sign too, we have a "chain of trust". Ok we have four parties now, the agent, the signing-agent(s) the enemy(hacker) and you.
What must be placed where? Well, assuming you are a warlord (server),
you need the public passwords of all your clients(agents) in a truststore to send them messages(download),
you need to know your private password to encode messages(posts, requests, uploads) your agents sent.
Assuming you are a agent(client/browser) of a warlord inside the enemys lines (open field of world-wide-web), you must store:
your private key, to send messages and sign messages of other agents
the public key of the warlord to encode orders of your master.
You have learned now that a certificate can contain aswell private keys as public keys. How to technically use them?
You lucky, the keytools is open source, download the sources from grepcode (click here) and you will have your implementations by copy-and-paste.
Some hints for mutual-authentication:
The server should not offer its public certificate because all authenticated clients already have the public certificate(key) in their truststore.
The client's certificate should be sent in a non-electronic way (printed as rf-code or whatever).
The client should presented the server's public key and the clients private key in two seperate physical letters (you may noticed if you use the electronic-cash-card (ec-card) you had two letters, one for the PIN and one for the ec-card).

Related

Lost keystore password, what are my options?

I have a keystore that I used to generate some .csr files, sent these off and got back .p7b files. However I managed to lose my keystore password, I saw there is a brute force java program to work it out however I know my password is 15 characters long and this would take a very long time. I also tried creating a new keystore from the old one, like some people had suggested but it still requires me to enter the password and fails without it.
Am I likely to run into problems if I just create a new keystore and import the certificates into that one or do I have to request new certificates?
Am I likely to run into problems if I just create a new keystore and import the certificates into that one
You will run into the problem that you can't do it. You've lost access to the private key.
or do I have to request new certificates?
You have to create a new keystore, keypair, CSR, get it signed, import it, ...
Actually it's a bit more complicated. In spite of its name, a Java 'keystore' can actually contain any combination of:
PrivateKeyEntry -- contains privatekey and matching certificate or chain, used to prove your own identity, particularly for an SSL/TLS server
TrustedCertEntry -- contains cert, usually root CA cert, used to verify other parties, including SSL/TLS client(s) verifying server(s)
(only in some formats, not common JKS) SecretKeyEntry -- not relevant here
See the javadoc for java.security.KeyStore. In fact the 'truststore' of CA certs used by SSL/TLS (including HTTPS) clients in Java to verify servers is normally a keystore file, by default JRE/lib/security/cacerts which is supplied as part of the JRE (for Oracle-formerly-Sun packages) or linked from it (for OpenJDK, at least in systems I've used).
Thus if you tell keytool to import your own certificate(s) to a new keystore file, it will do so -- but as trusted cert entry(ies) that can identify someone else, not as a privatekey entry that can identify you. The only indication is a subtle one: keytool will say Certificate was added (which means a trustedcert) NOT Certificate reply was installed (which means a matching privatekey).
If you then use this cert-only-not-privatekey keystore for an SSL/TLS server, it will not give any immediate or obvious error; normally it will instead reject all connection attempts as 'no cipher suites in common'. (If both endpoints have configured to allow 'anonymous' ciphersuites the connection will/may succeed with an anonymous suite, but this gives no security against now-common active attacks and therefore is not usually done.)
But this doesn't change the result: without the passphrase and thus access to the old privatekey, you're wedged and must start over. Note that if you used a paid CA many (IME most) of them allow 'rekeying' a cert for the same domainname(s) free or at a substantial discount.

Should the client have the same keystore as the server?

I am reading about the best way to create a secure connection between a client and a server.
Through this tutorial it seems that the certificate (and the keystore) is not only given to the server, but it is also given to the client.
Isn't this insecure? If the client has the certificate file (in the keystore), won't it have all the server private keys?
In the end what I want is to have a secure/encrypted connection between the client and the server, while the client itself proving to the server that it is an authentic client. Is this the right way to go?
Thanks!
As Boris stated in the first comment, the keystore contains the keys to authenticate and truststore contains the certificates that are trusted, as their names imply.
First of all, a certificate does not have to contain the private key. It is just an identity with a public key (with possibly signed by a trusted party, like CAs). That's why, if you use them appropriately, it is not insecure. What is the appropriate way of this? Here we go:
Before answering your question, i.e. the case that not only the server but also the client is authenticated, let's consider the usual case: only the server is authenticated by the client. In this scenario, we have three parties: Certificate Authority (CA), Server (S) and Client(C). To make it work, you should do the following:
Create a keypair for CA and store it in some ca.jks.
Export the certificate (containing only the public key, not private) from ca.jks and import it into another jks file, namely truststore.jks.
Create another keypair for S and store it in some server.jks.
Sign the certificate of S with the private key of CA. For this procedure, you need to generate a CSR (certificate signing request) from server.jks, sign the csr file with ca.jks and produce some crt (or pem, whatever you want) file containing the signed certificate. Finally you have to import this crt file back to server.jks. It is important to use the same alias as before.
Use server.jks at S as the keystore, and truststore.jks at C as truststore.
Keep ca.jks in a safe place. It is the root of trust.
In this way, C trusts CA since its certificate is in his truststore. Since S has a certificate signed by CA, C will trust S too. In other words, S is authenticated by C.
To achieve what you want, i.e. both parties are authenticated by each other, you will have two certificate authorities, namely CA1 and CA2. (They can be same of course, but I am writing like this for the sake of completeness.) You have to do the procedures above twice: once with CA=CA1 and once with CA=CA2. The first one is exactly like above. In the second one, you will create client.jks, sign it with CA2, and use public key of CA2 as the truststore of the S. (Just the roles of C and S are swapped.) In this way, both parties will authenticate each other.
As I said, you can use the same CA, which is very convenient and reasonable.
I know this is a long answer but be sure that I omitted most details and tried to make it simple. I hope it helps.
EDIT: Again, do not get confused: the client authenticates himself using his private key, stored in his keystore. Certificate is already a public thing...
Regarging your question, of course, if some thief steals the keystore file, then he can imitate himself to be the real client. The server cannot know who he is communicating with, he only validates the certificate. For such scenarios, issued certificates can be revoked. Search for revocation on the web. Simply, if you know that a client's keystore is stolen, you will inform the server about this through revocation, instead of regenerating all key material.
One corner case for this is, certificates are some kind of bindings of public keys with identities. For web servers, which is the usual case, their certificate binds their public key with their hostname, i.e. hostname is their identity. So if abc.com uses the certificate issued for xyz.com, your browser will give an error when you try to connect to abc.com. In Java world, this is called host name verification. The common name field of certificates are used for such identities. (When you generate using openssl or keystore, it may ask you a common name, and it is very important.)
If your clients are actually servers with static IPs or some valid domain names, you can use it. In this way, since the thief will try to connect from some other IP or domain, the server will detect it through hostname verification. However, usually clients do not have such stable identities, thus it is very hard to use this technique, so the thief may be able to imitate the real client.

JBoss/Java and SSL

Hi I'm a bit lost and hope you'll get me out of here. I'll try to be as clear as possible since I don't really understand/know how I should use certificates.
I've got an application that is supposed to communicate with another one using webservices and SSL. We both asked our main "Certificate Authority" to get certificates.
They sent us 4 files and a password for the .P12 file:
.csr, .cer, .key, .P12
Here is what I did :
* Configure JBoss to use SSL on 8443 and used the P12 file as the keystore
To test this I did a small Java class that call a webservices on this server, using :
props.setProperty("javax.net.ssl.trustStore", "/.../.../certif.p12");
props.setProperty("javax.net.ssl.trustStorePassword", "XXXXXXXXX");
props.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
The connection works, but I think I'm missing something as I did not use the other files.
If I send my .P12 file and the password to the application that is supposed to call my Webservices will it be ok/enough ?
Edit :
I forgot to mention that I should call a Webservice on the other application too, so it should be the other way around, do I only need a .P12 and pass ?
I've read a lot of thing about public key, private key, keytool but it's a bit messy in my head right now.
Thanks for any information !
They sent us 4 files and a password for the .P12 file: .csr, .cer,
.key, .P12
Ideally, you should have generated the private key (in .key) and CSR (in .csr) yourself and the CA should have come back with the certificate (typically in .cer) based on the CSR, which you would have assembled together to build your PKCS#12 file (.p12).
At this stage, you can discard the CSR. The PKCS#12 file should now contain the private key, its associated certificate and possibly the certificate chain attached. You could extract the .key and .cer files from that .p12 file later again. I guess you were given all these files because of the way they have been generated (using intermediate files), or for convenience, not to have to convert them yourself.
The Java terminology isn't ideal, but keystore and truststore are two entities of type keystore, but with a different purpose. The difference between the KeyManager and TrustManager (and thus between javax.net.ssl.keyStore and javax.net.ssl.trustStore) is as follows (quoted from the JSSE ref guide):
TrustManager: Determines whether the remote authentication credentials (and thus the connection) should be trusted.
KeyManager: Determines which authentication credentials to send to the remote host.
The javax.net.ssl.trustStore* properties are one way of configuring the TrustManager. The javax.net.ssl.keyStore* properties are one way of configuring the KeyManager.
Typically, there is no need for private key material in a trust store (unless you also use the same as a keystore). It's often better to use a separate truststore, which you'd be able to copy freely across machine, without worrying about leaking private key material.
What would make sense would be to build a new keystore (JKS) that you would use as a truststore, using the CA certificates (not sure if you've been provided with them).
You're not doing mutual authentication by setting the truststore only (there are no default values for the keystore, so they need to specify these parameters explicitly). If you want to use your client-certificate to connect to a remote party, you need to set it in the keystore (for example, using the javax.net.ssl.keyStore* properties in the same way you've done it for the trust store).
You could point both the keystore and truststore to the same .p12 file. The side effect is that other connections made by your service to other places (e.g https://www.google.com) would not be trusted, since it wouldn't contain the CA for those. That's why it might be better to create a separate "truststore keystore" (JKS might be easier) for the CA certificates. You could make a copy of the default cacerts (in the JRE directory), import your CA's certificate into it and use that.
I've got an application that is supposed to communicate with another
one using webservices and SSL.
Ok, stop here. Communicate how? I mean is it only server authentication i.e. your client application will authenticate the web service or mutual authentication and the web service will also request your applications certificate?
This is important as the files you present by the names seem to suggest the latter i.e. that mutual authentication is expected while your code you show is only setting SSL library for server authentication.
Since you are not providing context here I would say that:
.key has your private key
.p12 has your private key along with your signed certificate or perhaps the CA's root certificate (?)
cer could have your signed certificate or perhaps the root's CA
signing certificate that is considered as trusted in the domain and
has probably also signed the web service you want to communicate with
certificate (well that is a possibility/guess here since you don't
say much)
csr is your certificate signing request
I did a small Java class that call a webservices on this server, using
What you do in the code is setting the p12 as the truststore.
If you say this works then there is no mutual authentication only server side authentication and you are authenticating the web service using whatever is in the p12.
In this case the rest are not needed for communication.It is for you to keep especially the key file since this could be your private key and if you lose/someone steals this then your private certificate is useless/compromised.
I am not sure what your requirements on security are here, but it seems to me that you should probably look into it more.
Even for this question I just tried to do an educated guess based on the file names.....
I hope this puts you in some track to read.

TLS/SSL client authentication using a client certificate which comes available at runtime Android/Java

Suppose I have an application which in some way retrieves a client certificate (private/public key pair) at runtime via a secure channel (so I don't have this client certificate at build time).
How can I use this client certificate for client authentication without using keytool and not using some on persistent/ondisk keystore. So I do not want (actually I can't) to import it using a command line keytool?
Actually I want to replicate the functionality done in libcurl. You just set the client certificate (with private key) and your done. It doesn't involve a keystore.
All this has to be done in Java/Android.
You can do it in Java by defining your own KeyManager as described in the JSSE Reference Guide. I can't speak for Android.
I just got this working and I dont think you'll be very happy with my answer but it does work :)
So the hard part is to get the pkcs12 certificate you need to perform client authentication, if your certificate is already in pkcs12 then you've got all the hard stuff out of the way and you can refer to the second answer on SSL client authentication in Android to see how to use that certificate.
if you just have a public private key pair and not a pkcs12 certificate then you will need to make one. As far as I could tell there is no way in java/android to create this certificate so you need to use the android NDK and openssl.
if you download the openssl-android project from https://github.com/guardianproject/openssl-android you can use it to build openssl. By default it compiles as a .so shared object but only some of the android devices I tried to run this code on were able to link against libcrypto, so, although im sure there is a better way I went into the Android.mk files and replaced include $(BUILD_SHARED_LIBRARY) with include $(BUILD_STATIC_LIBRARY) in a few places so that I could compile a .a static library.
I then used the info from Android NDK: Link using a pre-compiled static library to link the libcrypto.a I compiled to my native code.
This native code uses openssl to first create an X509 certificate and then uses it to create a PKCS12 file which can be used in the manner I mentioned before located at SSL client authentication in Android
first you need to get your public and private keys into native land as EVP_PKEY pointers which can happen in a variety of ways based on what format your keys are in then you can use the following code to create an X509 certificate
X509 *public_key_cert = X509_new();
X509_gmtime_adj(X509_get_notBefore(public_key_cert),0);
X509_gmtime_adj(X509_get_notAfter(public_key_cert), (long) 60*60*24*365);
X509_set_pubkey(public_key_cert,evp_pub_key);
This creates the most minimally valid X509 certificate which is valid for 1 year. You may want to do other stuff like sign the certificate if you are going to run your own certificate authority, or set any of a large set of headers which contain various bits of information.
next you need to create the pkcs12 certificate using the X509 cert like this:
PKCS12 *pkcs12 = PKCS12_create(password, "Some Sort of Friendly Name", evp_priv_key, public_key_cert, NULL, 0, 0, 0, 0, 0);
password is a char* containing the password which will be used to encrypt the private key using triple-DES
Now that you have a pkcs12 certificate you can go over to SSL client authentication in Android and get client authentication going.
Good Luck!

Verify certificate against Java certificate store via CLI

How can I verify an X509 (or DER-formatted) certificate against the Java certificate store via the command line?
I've looked into using the keytool utility, but it looks like it only handles import/export/display functionality (no verification).
EDIT: It looks as though keytool can be used for verification, but only if an import is attempted. I suppose a better way of asking this questions is whether or not a more passive approach (as in: not modifying the keystore) is available. Thanks!
You can use keytool to export the needed certificates (those that are in the chain for the one you need to verify) from the Java keystore into X.509 files. Then, concatenate them together into one file. Finally, use openssl to do the verification.
openssl verify -CAfile concatenated-certs.crt cert-to-verify.crt
Not a perfect solution since it involves popping the certs out of the truststore, but it ought to work given what you are starting with.
This page could be oversimplifying:
http://java.sun.com/docs/books/tutorial/security/toolfilex/rstep1.html
But it doesn't look like even import with keytool does a true verification of a certificate. I'm not seeing any description of verifying the signature of the incoming certificate against the signature of another trusted certificate.
jarsigner will verify a signature on a signed jar, but doesn't do anything to verify the signature on the certificate used to sign the jar.
I'm afraid you'd either have to write a tool to do the verfication, or look for a commercial tool that does it. I would think that some of the PKI tool kits would have a certificate verification tool that would do this.

Categories