Storing an X.509 certificate in a Java keystore - java

I am trying to store a proxy X.509 certificate into a keystore. The certificate is generated using bouncycastle library, the problem is that I do not have the secret key for the certificate and from what I understand is that to store it in a Java key store I need the secret key. Furthermore I can't seem to convert the certificate into Java's own implementation of it.
I want to store it in a keystore so that Axis2's Rampart could attach it to SOAP messages according to our own security architecture.
IF anyone can kindly explain to me if there is a way to do this or if I am missing something important I would be thankful

from what I understand is that to store it in a Java key store I need the secret key
No. You don't need the private key to store a certificate. You only need that for your own certificate. Just use keytool -import.

Related

Certificate to java keystore

I have been given a certificate and asked to use it to make http calls via my application (I'm using Mule which is based off Java).
The certificate I've been given is a .cer file. It is a certificate specific to my company which I think means that it has the public key of that server.
The company who have given my the CER file have given me a password to it. e.g. abc1234
To use it I first ran the command as shown below...
keytool -importcert -file myCert.cer -keystore keystore.ks -alias 1
I then plonked it into my code as follows...
<http:request-config name="HTTP_Request_Configuration" protocol="HTTPS" host="hostname.com" port="443" doc:name="HTTP Request Configuration">
<tls:context>
<tls:key-store type="jks" path="keystore.ks" alias="1" keyPassword="changeit" password="changeit"/>
</tls:context>
</http:request-config>
When I call that endpoint in my application I get ‘Error 403: Missing authentication’.
I never had to enter in the password 'abc1234' anywhere throughout this process and I'm thinking that is why I'm getting the 403. Where does that password need to be provided?
thanks
Thanks all for your feedback. All the answers and comments here definitely helped me.
In the end I found out that certificates do not have password (as mentioned in the comments) and that the password listed was not relevant.
I ended up finding out that the 403 was caused by an SSL handshake error and that it was not finding the CA certificate.
I was only able to find that out by turning on the SSL handshake logs.
Certificate files are not password-protected. Key stores are. So it's possible that what they sent you is not a certificate, but a complete key store. Such a key store might have been intended to support TLS client authentication—authentication with a key pair—instead of a password.
A certificate carries half of a key pair. To use it for authentication, one also needs the private key. Normally, to obtain your own certificate, you'd generate the key pair yourself and send the public key to someone to be bound together with your identity as a certificate. The standard format for sending your public key is called a CSR, or certificate signing request.
The Java keytool allows you to generate a key pair, and a CSR for that key, then later, you can import a fully signed certificate. Did you do any of these steps? It would also be possible for someone to do this process for you, and send a complete key store, but then they know "your" private key too.
Alternatively, the certificate you received may be so that your client can authenticate the server, and the password is what you are supposed to use to authenticate your client after you connect, and isn't protecting the file at all. But if the certificate really has your identity in it, as you say, this doesn't make sense.
You should have added it to your truststore, not your keystore. It is a certificate to be trusted, not to be used as your own certificate. It isn't your own certificate.

Creating a truststore to only validate certificate signed by a custom CA in JAVA

I hope this isn't a duplicate.
I'm currently working on client server game based on netty with a client on Android. I'm trying to make a secure login process so I tryed using ssl on top of java socket.
I managed to create a self-signed certificate and to use SSL. The problem is that the example source code i found use à custom TrustManagerFactory which doesn't make any check upon certificate validity. Since I don't wan't to allow Man In The Middle attack i searched for more information on SSL handshake and here is what i understood:
To initiate SSL session, the client send a request to the server.
The server which own the certificate(.jks or .bks) extract public informations into a X509 certificate and send it to the client.
The client check for the validity of the certificate ( In my current solution do nothing)
If check succed retrieve the server's public key from the certificate, generate a random key, encrypt it with the public key and sends it to the server.
The server use his private key to decrypt the randomly generated key.
Both client and server now share the same random key and they start a comunication using this key for symetric encryption ( like AES ).
I don't need to accept certificate from anyone else than my own server so i thought about 2 solution:
Save the X509 on client side and create à custom TrustManager witch only accept this certificate. This solution seems easy to implement but rather hard to maintain since every certificate change on server side would need to update X509 certificate on every client.
Create my own CA certificate sign my ssl certificate with this certificate and manage somehow to tel my client to only trust all certificate signed with my CA.
What i understood about CA authentification is this :
A CA root certificate is a normal certificate that contain a key pair.
signing a certificate with a CA mean adding at the end of the being-signed certificate a hash of the whole certificate encrypted with the CA private key.
this signature is contained in the X509 certificate along with some informations about CA.
To check certificate validity, the client generate certificate hash and compare it to the decrypted hash (using CA public key) contained in the X509 certificate.
So if i'm not mistaking in all of this, if i want to implement my second solution, I need to provide a CA certificate to the client so that he can check certificates. I've seen that it is possible to init à TrustManager with a truststore. I asume it must be a different certificate from the root CA one since the whole security of this depends on my CA private key 's confidentiality. So my questions are :
What should this client truststore contain and how to generate if from my root CA ??
I have red that ssl engine is broken for self signed certificate. So is my second solutions viable on android?
If this can work, how can i invalidate my certificate if i see that someone manage to get my private key somehow? I have red things about crl but i don't know how to generate/use them in my truststore?
thanks in advance.
I can only answer part of your questions:
The truststore should contain your CA, you can generate it with keytool:
http://docs.oracle.com/cd/E19509-01/820-3503/6nf1il6er/index.html
No problem you can implement this in android in the same way than in java using java.security.* and org.apache.http.* classes. One warning, for android versions <=2.3, you could need to implement a workaround as some public CA are missing and it doesn't support miss-ordered certificates chains. I can give you more details if needed.
I don't know
Edit:
A good turorial:
http://nelenkov.blogspot.com/2011/12/using-custom-certificate-trust-store-on.html

Java Keytool for SSL: CSR Aliases, Keys and Keystores

I read this article on how to use keytool to generate CSRs for your organization. It was simple and easy, but left me with a few questions that I couldn't find clear, descriptive answers to:
What is Java's concept of a CSR alias and why would you want to use one? Where is this alias field stored and what other tools/APIs have access to it?
What is the difference between a key and a keystore?
What is Java's concept of a CSR alias and why would you want to use one? Where is this alias field stored and what other tools/APIs have access to it?
First of all, java uses keystores to keep keys (and certificates) inside. Single keystore can hold many certificates, so you need a way to differentiate them. That's what aliases are for. Having a keystore, an alias (and a password if needed) you can get the certificate from the keystore using Java Crypto API (specifically classes like Keystore). Here, you have a an example of how the Crypto API can be used to load a key from keystore
What is the difference between a key and a keystore?
The keystore is a container. The keys are kept inside keystores.
A keystore is a file format used to hold certificates and private keys, and alias is used to identify each entry in the keystore.

Using PKCS 7 Cryptography

I need to encrypt and sign data using PKCS7(CMS).
I am using bouncy castle provided api to achieve this using java .
Till now what i understood is i need to follow these steps
Need to generate a key pair private & public key using some algorithm say RSA
Certify it with X509 certificate
Convert it into PKCS7 key format like p7b
Generate java key store using keytool some *.jks file
Generate the Certificate Signing Request (CSR) using keytool command *.crt
Become self CA(Certificate Autority) and certify
Import key from keystore created in previous stem and encrypt sign and decrypt data
I still need to figure out what steps i need to follow to sign,encrypt,decrypt data.
My question is
Is my steps are correct ?
How do i certify key pair generated by RSA algorithm and convert into PKCS7 key format
How do i become self CA and certify
I got this to encrypt and sign, still i am confused with steps to follow and also most of them are deprecated.
What you need is not BouncyCastle.
You need OpenSSL and a guide.
OpenSSL
How to set up your own certificate authority
How to create a self-signed certificate
How to use a certificate in Java
Alternatively, to generate and store an RSA key using Java:
Generate RSA key pair and encode private as string

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!

Categories