I need a clarification\confirm for keytool and Keys in general.
Many many sites show this is the way to obtain a keystore with a certificate:
keytool -genkey -keyalg RSA -alias my-certificate -keystore mykeystore.jks -validity 3600 -keysize 2048
And if u export it your can clearly see:
-----BEGIN CERTIFICATE-----
MIICVjCCAb8CCAogFQkp...
...rI7KvuXHX2JWNYLdBvC8V6aXAiIb
OaSAB3DoscgOqDh58bw5vEFwjxVo...
-----END CERTIFICATE-----
So this is a certificate indeed. But from this can be extracted only public key.
So we can say that a certificate is Secret key?
On the other hand with keytool command:
-genkeypair
generates a key pair (a public key and a private key). Private for the server and public for the others.
So basically certificate\secret key isn't the same as private key?
Both methods get public so basically a certificate is a private key?
In short keystore contains key pairs, and a key pair consists of a public and a private key. So keytool creates both.
What you call certificate is public key, since private keys is highly confidential to your application server, it should not be transfered insecurely, if possible it is not transfered at all. Which means you should create a keystore in the application server and from that keystore you should extract public key. And after it is signed by a certificate authority, it should be added to keystore to create a keychain.
A much detailed answer can be found in here
keytool creates two keys, a private key, which you use for signing, encrypting, decrypting, i.e. anything that needs to be traced back to you. In order to trace something back to you, to validate your 'identity' you give others your public key certificate. This wraps your public key with identity information. If it's a self signed public key certificate then you are saying you are, for example, ServerA but no-one can really verify you're ServerA as ServerA is claiming it's ServerA. To fix this, you export a Certificate Signing Request (CSR) from your keystore and send it to, e.g. Verisign who validate you are ServerA and then they sign the certificate. What you end up with is a public key certificate saying you are ServerA and that claim is signed by Verisign using their private key and just about every entity out there has the Verisign public key certificate so they can verify Verisign's signature which means they then trust you as ServerA. You then distribute your public key certificate and everyone can encrypt messages to you, knowing that you are indeed ServerA, because of the root signature from Verisign.
Related
PEM file from the server side which is in the following format when opened:
-----BEGIN CERTIFICATE-----
somestuff1234
-----END CERTIFICATE-----
I'm trying to convert this to get two JKS files (A trust store and key store) which I can call the server with using my java application through SSL.
Can anyone help in a easy break down on how to do this using openssl and then the java keystore? I tried following the instructions in: https://docs.oracle.com/cd/E35976_01/server.740/es_admin/src/tadm_ssl_convert_pem_to_jks.html
But I couldn't import the keystore successfully as for some reason it was empty. PS when following these instructions I created the PKSC12 from der without a private key inputted since I wasn't provided one.
Do I need to use my own private key which I need to create as well but not sure if it is needed since I was only given the certificate? I've been told intermediate certs are sent in the TLS handshake.
Thanks for any help on this.
Try to run your java code with debug mode and specific truststore regarding the SSL server like described here:
How to configure trustStore for javax.net.ssl.trustStore on windows?
If the only thing in that PEM file is what you've posted:
-----BEGIN CERTIFICATE-----
somestuff1234
-----END CERTIFICATE-----
you will not be able to create a full keystore suitable for use as a TLS server that accepts connections.
You need the private key corresponding to the certificate for that.
Do I need to use my own private key which I need to create as well but not sure if it is needed since I was only given the certificate?
No - along with its identifying data, your certificate has a public key in it. The entire certificate was cryptographically signed by your CA - which is how the "trust" is transferred to your certificate. The public key in your certificate was derived from a specific private key.
Why won't it work? Because data that's encrypted using the public key in your certificate can only be decrypted using the private key that public key was derived from.
Your certificate will only work if it's paired with the correct private key.
But:
I created the PKSC12 from der without a private key inputted since I wasn't provided one.
You must have a private key along with your certificate to be able to run a TLS server.*
EDIT:
And you must have the proper private key paired with your certificate to use it as a client certificate when connecting to a TLS server for the same reason.
Also, a TLS certificate is public - if it were all you needed to prove your identity, publicizing that would make it useless. Your possession of the appropriate private key is what proves that the certificate is your certificate and not mine or anyone else's.
Your TLS server or your client connection to a TLS server isn't going to work until you locate the proper private key for the certificate you have. If you or your organization have lost that private key, you have to create a new private key and go through the process of creating a new certificate from that new private key.
Because without the correct private key, the certificate you have now is utterly useless.
* - Technically not true. The TLS standard does support "anonymous" cipher suites that do not require any certificate or private key. But almost no application supports anonymous cipher suites. OpenSSL only supports anonymous cipher suites if you compile it from source yourself, for example.
I want to hit the REST endpoints of a Server, say xyz.com. They have provided certificates in PEM format which I should be including in my application while connecting to their endpoints.
My application is written on Spring Framework and I need to convert PEM to P12 format as Spring won't accept PEM. This is how I convert:
openssl pkcs12 -export -out certificate.p12 -inkey private.pem -in server_cert.pem
Where,
certificate.p12 = resultant p12 file
private.pem = private key
server_cert.pem = certificate files of the server
The error I get is:
No certificate matches private key.
Now my questions:
Whose private key should be used to generate the P12 file from the PEM file?
If the private key of client is used to generate p12, how could it possibly match with the certificate (error message becomes obvious)?
Why would I need my private key to communicate with the server? As per my understanding, during an SSL session, the private key of the client doesn't come into the picture. Or is my understanding wrong?
If the private key of the server is used to generate p12, why would they share it?
I'm a novice and therefore any links/suggested-reading/sources/answers are welcome.
If you look at how the client-authentication works, in the 'Negotiation Phase', the second from the last point says:
The client sends a CertificateVerify message, which is a signature over the previous handshake messages using the client's certificate's private key. This signature can be verified by using the client's certificate's public key. This lets the server know that the client has access to the private key of the certificate and thus owns the certificate.
So to answer your questions:
You should be using the private-key that was given to you.
A PKCS12 is a type of Java KeyStore, which is similar to a standard JKS. It can contain a list of keypair's. But the internet standard of PKCS12 is to have only 1 key pair entry, i.e., 1 Private Key with its associated certificate-chain. Since the private key and the certificate chain were given to you as separate entities, you should be constructing the PKCS12 yourself, which you will be using in your code, to authenticate your client to the server that is providing you the service.
If you look at the steps of how the handshake happens at the protocol level, you should see that the client's private key (your private key) is used to sign some data and send to the server, where the server will be validating the authenticity of the message based on your public key. Once the server validates the message, it will come to a conclusion that you posses the private key.
You wouldn't be given servers private key. You are given your (users) private key, which you guard it and shouldn't be giving to anyone.
There might be something missing or trivial error while you are constructing with p12 with the private key and the certificate chain, which is causing to fail. If it doesn't work out, you could also construct the p12 using the KeyStore api programmatically.
These are the facts:
I have a client(android)-server(java - Ubuntu 14.04)-program with which I transmit my gps-data from my smartphone every 5 minutes to the server saving it into a mysql-database.
My problem is that I do not want to transmit my GPS data plain. So I want to use SSL, to verify the client(my smartphone) to the server(making it impossible for someone else to connect to the server - no handshake) and of course to encrypt.
My main issue is about understanding the keystore, truststore process.
With
keytool.exe -genkey -keyalg RSA -keysize 2048 -alias -serverKey
-keystore serverKeystore.jks -validity 1095
I am creating a new keystore (if not existing) named serverKeystore.jks. This keystore includes the private key and the public key wrapped by the certificate.
I can export the certificate with
-keytool.exe -export -alias serverKey -keystore serverKeystore.jks -file server.cer
So based on this tutorial he now creates a clientkeystore:
keytool -genkey -keyalg RSA -alias clientKey -keystore
clientkeystore.jks -validity 999 -keysize 2048
and I export the client.cer the same way like I did with the server before.
Now he adds the server.cer to the clients-keystore and the clients.cer to the servers-keystore. But now serverKeystore and clientKeystore have created a different private/public key-pair. The server is now aware of the clients public key and the client is now aware of the servers public key. That way the client can encrypt the plaintext with the public key of the server and the server can then decrypt it with his private key. Is this correct?
If so where is the truststore? Is the truststore the server-keystore storing the client.cer and that way trusting this client and vice-versa?
Now he adds the server.cer to the clients-keystore and the clients.cer to the server's keystore.
Wrong here. You should add the exported certificate to a truststore in each case. Export from server keystore to client truststore, client keystore to server truststore.
That way the client can encrypt the plaintext with the public key of the server and the server can then decrypt it with his private key. Is this correct?
It's correct in theory but it isn't used that way. SSL negotiates a symmetric session key. The certificates and their keys are only used for authentication, not for encryption.
If so where is the truststore?
See above.
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
Is it possible to regenerate a private key in a .JKS keystore using keytool or equivalent?
I've been supplied with a certificate and a JKS keystore, but on importing the cert it looks like the private key that was used to generate the CSR has been deleted.
I can see how to create a new keystore with a new private key, but this won't then match the CSR or certificate.
No, that's the whole point of asymmetric cryptography: making it impossible to produce the private key when knowing only the public key (which is contained in the CSR and in the certificate).
If you could re-generate the private key only from the CSR or the certificate, anyone could impersonate the entity to which the certificate has been issued.
If you've lost your private key, you'll simply have to create a new key-pair, submit a new CSR and get a new certificate. Some CAs allow this sort of re-keying for free as part of their contract within the duration of the initial certificate.
EDIT: Just to clarify what a CSR is.
To apply for an X.509 certificate, you must:
Generate a public/private key pair. By nature, the public key can be publicly distributed, because it's not sufficient to obtain the private key (at least not in a reasonable time).
Submit that public key with your identity information to the Certification Authority. This can be done using:
A Certificate Signing Request (CSR, PKCS#10), which contains your public key and the data you would like to be in the certificate (e.g. the Subject DN you want). Although very similar to the data in a certificate, this data should mainly be used by the CA for identifying the request itself, since CAs doing their job properly should check what they put in the certificate, not just turn the CSR into a certificate blindly. The CSR itself is signed using the private key matching the public key in the certificate. It's effectively very similar to a self-signed X.509 certificate (without Issuer information and validity dates), but isn't one.
SPKAC or CRMF for in-browser certificate applications.
The CA then takes this CSR (or equivalent) and makes the necessary verification outside this process to vet the pieces of information it wants to embed in your certificate, and issues your certificate (by signing it with its own private key). It's effectively vouching for the binding between your public key (extracted from the CSR) and the information it embeds in the certificate (e.g. your name and/or the domain name for which this cert is). It sends you back this certificate.
You then have to use this certificate in conjunction with the private key matching its public key. Some tools do this using separate files, it's also possible to import the cert back against the private key entry in a keystore.
Having the CSR or the cert without the private key is of no use. You can quite easily create a new CSR again, but you'll also need to create a new key pair. The most important part of the CSR is the public key, and to have the matching private key. You can discard the CSR otherwise.
Is it possible to regenerate a private key in a .JKS keystore using keytool or equivalent?
Yes, but regenerate the private key and CSR. The CSR is submitted to the CA where you are provided a new public key.
You can reimport to the keystore anytime using the following command:
keytool.exe" -import -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file .\certificate.cer
Make sure you also import the certificate to both paths for the newer JDK releases:
C:\Program Files\Java\jdk1.6.0_31
The newer releases also deploy a separate JRE:
C:\Program Files\Java\jre6
Failure to do so may result in the following exceptions in log:
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
To regenerate your private key and CSR, you can use the following command:
$ openssl req -new -newkey rsa:2048 -nodes -keyout private.key -out signing request.csr -config openssl.conf
I had the same trouble (my private key was accidentally deleted from keystore) and there was just one way to recover it: replacing the keystore file (*.jks) with a backup. So I recommend to always make backup with all files related to SSL, and if you delete anything by mistake on keystore just replace the file with an older one.