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.
Related
I've just receive a certificate, containing those files:
- Root CA Certificate - AddTrustExternalCARoot.crt
- Intermediate CA Certificate - USERTrustRSAAddTrustCA.crt
- Intermediate CA Certificate - SectigoRSADomainValidationSecureServerCA.crt
- Your PositiveSSL Certificate - www_guerrilla_app.crt
and also the PositiveSSL Certificate in text format.
I would like to know if it is possible to generete the Private Key from the command line, maybe using Java or other tool
No. If you could it would mean the entire https internet is broken. You need the key from whoever generated the CSR.
The proper workflow is: create a SSL key, generate a Certificate Signing Request (CSR) with that key, provide the CSR to the SSL Certificate provider (PositiveSSL), have them sign it and give you a certificate.
To add to what Kees answered - you will generate CSR and private key together. This private key you will required when add them to load balancer to nginx
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.
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.
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
I am trying sign an app using keytool, but I dont have a keystore file.
Do I need to generate this file myself or should I receive it from from code signing authority ?
If so what files do I require to generate a keystore file ?
Thanks
The key store is a database for your keys. The process of "signing" an app (e.g. with jarsigner) is roughly the following:
You create a private/public key pair with keytool.
You then create a CSR (certificate signing request)
A CA (certification authority) processes your request and gives you a certificate.
You have to import the CA response into your keystore.
You may create self signed certificate to get a feeling of the process. You may use openssl.
You have the answer under your fingertips... keytool is your friend...
http://download.oracle.com/javase/1.3/docs/tooldocs/win32/keytool.html
Keystore Creation
A keystore is created whenever you use a -genkey, -import, or -identitydb command to add data to a keystore that doesn't yet exist.
More specifically, if you specify, in the -keystore option, a keystore that doesn't yet exist, that keystore will be created.
If you don't specify a -keystore option, the default keystore is a file named .keystore in your home directory. If that file does not yet exist, it will be created.