I used windows and linux machine to create java keystore (JKS) by java keytool. When i run the keytool command mention below:
keytool -genkey -alias TESTSSL -dname "cn=Test.com, ou=testlab, o=myorg, c=UK" -keyalg "RSA" -keysize 2048 -keystore TESTSSL.private.jks -validity 10 -storepass XXXXXXX
It prompt to enter keystore password and key password.
The query is that, I want to know where both passwords are stored and in which form. Is it stored in keystore file or somewhere else in OS(If this is the case, know the exact location).
Any information related to this highly appreciated.
Note you are actually creating the default format of keystore, assuming this file doesn't exist at the time you run keytool; through Java 8 the default is JKS, but from 9 up it is PKCS12. (Naming the file something.jks does not control the format, any more than naming it something.lollipop would make it a child's sweet.)
If you specify -storepass whatever on the commandline as you stated, it should not prompt for keystore password -- at least not on that operation; if you run keytool again to (re)use the same file, that will prompt unless you again specify it on that commandline. Similarly if you specify -keypass whatever on the commandline, when needed depending on the operation, it should not prompt for key password.
For JKS JCEKS and PKCS12, the password(s) are not stored at all. Doing so would be grossly insecure. Instead, the password(s) plus 'salt' (a randomized value) are processed by a one-way 'key derivation' algorithm to create the key(s) used to encrypt at least the privatekey entries in the keystore, and to authenticate (MAC) the entire keystore. PKCS12 as implemented in Java (weakly) encrypts the certificates as well as the privatekeys; JKS and JCEKS do not. PKCS12 as implemented in Java may not support a private-key password differing from the store password.
If you can't or don't supply the correct password(s) when using the keystore file it may fail depending on exactly what operation(s) you try to do, so it is your job to remember them, and if necessary transfer or distribute them. If you need to do this on a scale difficult to manage manually, there are password-management tools -- which can handle passwords for all things, not just Java keystores -- of many kinds and from lots of sources.
For non-file-based keystores, like PKCS11 on some systems or the OS-provided store on Windows, how the password is implemented and used -- if at all -- depends on the particulars of that keystore, although storing the password would usually be poor or bad practice.
The key password and keystore password are stored in the keystore itself. It's self-contained. That way the keystore is portable and can be sent to others who can open it (provided they know the key[store] password).
Related
I have all the required files to import to my apache tomcat, that is:
the Certificate Request file (CSR file)
the RSA PRIVATE KEY file
the certificates (root, intermediates and Entity/Domain) that was sent to me by the Certificate Authority.
Now i need to import them to my apache tomcat server.
My question is, given that i havent created any key store to my server (the CSR and private key were sent to me, i didnt created them with e.g. keytool), what should be the next steps? Should i have to create a new keystore through keytool -genkey command (which alias?) ?
And if so, which of the files above should i import? As far as i can see the keytool command doesnt support to import an existing CSR.
The extension .crt is often but not always used for certificates in PEM format. First, set aside the CSR; you won't use it. Look at the contents of the privatekey file and each certificate file; do they each have (usually begin with) a line in the format -----BEGIN {one or more words}----- then several lines of base64 and then a similar END line? If so those are PEM files and the content you need is one privatekey and several certs, exactly as you listed. See also (cross) https://crypto.stackexchange.com/questions/43697/what-is-the-difference-between-pem-csr-key-and-crt and https://security.stackexchange.com/questions/183072/pem-cer-crt-p12-what-is-it-all-about .
As noted in the Q Piotr linked, modern Tomcat (8.5 and up) can directly use PEM files for privatekey and cert(s). Older Tomcats with the 'native' SSL option (aka APR, Apache Portable Runtime, which wraps OpenSSL) also do this.
To use PEM data in older Tomcat using Java SSL (JSSE), or other Java applications, see
Convert a CERT/PEM certificate to a PFX certificate
Importing the private-key/public-certificate pair in the Java KeyStore
How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application?
Converting pem with multiple certificates to java keystore
Converting PEM Certificate for use in JAVA Spring Framework
Converting PEM to PKCS12 and import to Java Keystore
Note PFX is the same thing as PKCS12, and while in olden days it was often necessary to convert to PKCS12 using openssl pkcs12 -export and then to JKS using keytool -importkeystore, Java versions since 2017 should accept PKCS12 as a keystore and in fact j9 up make it the default for newly created keystores.
Ok first I'll say what I know about how SSL works.
Most of all I need to understand how the client certificate works, because I was setting up mTls istio gateway and had trouble with it.
So, firstly I need key-pair, private and public. If I understood correctly, i create them next with the following command:
keytool -genkey -alias myKeyPair -keyalg RSA -keysize 2048 store.jks
If I look in the keystore there will be one PrivateKeyEntry. Next I create request for certificate:
keytool -certreq -keyalg RSA -alias myKeyPair -file request.csr -keystore store.jks
After a while, I received a signed client certificate client.cer and certificate trusted CA ca.cer.
Now there are questions:
First, i tried to send request from curl. But curl needs private key which stored in jks. I dont have openssl and cant get it, so i extract private key using java code. But the result was always the same: istio gateway: peer did not return a certificate
Second, I tried using java.net.http.HttpClient with SSLContext setting containing my jks. And it worked. But firstly I had to put ca.cer and client.cer in my jks. And this I cannot understand: why do I need to put ca.cer? Because without ca.cer stored in store.jks i have error certificate validation.
Also when I put client.cer in jks, keytool displays a warning: Certificate already exists in keystore under alias <myKeyPair>. Do you still want to add it? Why does it think privateKeyEntry and trustedCertEntry are the same?
Meta: a poor answer due to the vagueness of the question, but much too long for comments.
First, i tried to send request from curl. But curl needs private key which stored in jks. I dont have openssl and cant get it, so i extract private key using java code. But the result was always the same: istio gateway: peer did not return a certificate
Either your 'extract' was wrong or the way you provided it to curl was wrong, or both, and you described neither. First, to be clear, like any client doing client auth, curl actually needs the privatekey and certificate, and usually any applicable chain certificate(s). What file format(s) you must use, and whether a single combined file or separate files (added:) or none at all as it turns out, depends on the curl build you are using: curl supports seven SSL/TLS implementations, and the ways to provide client-key-and-cert vary among them. Use curl -V (uppercase) to see how it was built, then look at the portions of the man page, on your system or on the web, that apply to that implementation.
Second, I tried using java.net.http.HttpClient with SSLContext setting containing my jks. And it worked. But firstly I had to put ca.cer and client.cer in my jks. And this I cannot understand: why do I need to put ca.cer? Because without ca.cer stored in store.jks i have error certificate validation.
Possibly it is a 'chain' or intermediate CA cert. An SSL/TLS client (like a server) is required by the standard to send any chain cert(s) needed to connect the end-entity (client or server) cert to normally a 'root' in the receiver's truststore. (Since RFC5280, and confirmed by RFC8446, it is actually possible to use an anchor that isn't a root, but it is rare to do so.) Possibly it is even a combination of chain cert(s) and root (or anchor). (Some reliers sometimes can still build the chain to validate a cert when it wasn't correctly sent; browsers especially tend to do this, but most servers not.)
Look at it and see. If it is PEM format you can see with any text display or edit program how many certs it contains. If it is a single cert you can display the details with keytool -printcert -file $file -- or since you already imported it, keytool -list -v -alias name -keystore $ks [-storepass $pw]. If it is multiple certs in PEM format you can break it apart with an editor and display each one separately. If it is multiple certs in DER format you won't be able to handle that easily, but fortunately that format is rarely used. openssl x509 [-inform pem|der] -text -noout is also commonly used to display cert file details, but you say you can't use it.
Also when I put client.cer in jks, keytool displays a warning: Certificate already exists in keystore under alias . Do you still want to add it? Why does it think privateKeyEntry and trustedCertEntry are the same?
If you only did this once, and correctly, it shouldn't. Given separate cert
files, you should keytool -importcert the client cert to the alias of the privatekey entry you created, and used to create the -certreq, which in your example is myKeyPair, after you keytool -importcert any needed chain cert(s), and optionally the root or anchor, (each) to a different alias. (It is often convenient, but not required, to use simple words like root, imed, imed2 etc. as aliases.) Alternatively, if you have the whole chain as a single file, either PEM sequence or DER sequence, or 'p7b' (a dummy PKCS7 SignedData with no data and no signature, commonly used as a container for one or more certs, such as a chain) either PEM or DER, you should import that chain in a single operation.
Before I start, I have looked at 2 other questions:
keytool error: java.lang.Exception: Public keys in reply and keystore don't match
And
java.lang.Exception: Public keys in reply and keystore don't match
But I believe that the error comes in the way I am generating the csr that I submit to my provider(Digicert). I will detail my commands below, notice that this is the way our department has always done this and up till this point I can't understand why this is not working (I am also not capacitated at all to do system administration things, but this landed on me)
First - Generating the keystore
keytool -genkey -alias aliasItem -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -keypass <password> -dname "CN=server.domain.whatever, OU=IT, O=SOME NAME, L=City ST=State C=COUNTRY" -keystore keycerts -storepass <password>
I changed the important items as you might well assume for security concerns. Afterwards:
keytool -keycerts -keyalg RSA -sigalg SHA256withRSA -v -alias aliasItem -file outputfile.csr -keystore keycerts
After I get the csr, I submit it to my provider, there is no copy/paste error in this case since I import the file directly. They provide two .crt files, one from the service provider, and one for the server i am requesting it for. After I move these files to my server and attempt to import the service provider's .crt to the keystore I get an error, this is the command I use for importing the .crt to the keystore:
keytool -import -v -alias aliasItem -file <Provider>.crt -keystore keycerts
Which outputs the error:
keytool error: java.lang.Exception: Public keys in reply and keystore don't match
java.lang.Exception: Public keys in reply and keystore don't match
at sun.security.tools.KeyTool.establishCertChain(KeyTool.java:2688)
at sun.security.tools.KeyTool.installReply(KeyTool.java:1940)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:855)
at sun.security.tools.KeyTool.run(KeyTool.java:194)
at sun.security.tools.KeyTool.main(KeyTool.java:188)
I have tried changing some parts of the scripts a total of 8 times now, all using the notes and documentation provided by me with no positive results. What strikes me as odd is that this server is identical in all aspects to another one of our test servers, for which I had done this before with no issues. I am still trying to do different things to solve my issue, but due to my limited knowledge in this I believe that there has got to be something I am doing from the beginning that might be wrong.
Any input will be greatly appreciated.
The second command for generating the car seems to be incorrect because "-keycerts" is an illegal parameter. IT must be "-certreq" .
Now, the error states that the private key does not match with the certificate which you are trying to install. Kindly check the below
a) Please make sure you are trying to use the same keystore file which you used to generate the csr
b) Please check while importing you are using the correct alias name. The alias should match with the one you mentioned while generating the keystore file.
c) Please make sure you are importing the correct server certificate and not the intermediate or root. Digicert must have provided you all the three files namely, Server certificate (CN of this certificate must match with the one when you generated the csr file and this is the one which needs to be imported), Intermediate and root.
If the above steps don't work then you have to generate the new csr and keystore file and ask Digicert to Reissue the certificates. They will do it for you free of cost.
Can you please advise if key password and keystore password using ikeyman tool are they same or different because ikeyman tool ask only keystore password?Help please..
thanks
Ikeyman uses 1 passphrase to encrypt the keystore (container) and its contents. There is no ability to protect the individual private keys with a separate passphrase. Contrast with openssl pkcs12 handling -- the entire keystore can have one password, and each RSA key inside can have a separate passphrase.
I have a java web project and I have used few certificates to contact a URL. Now I have deployed project as a WAR file in a Unix server and my project has a certificate issue.
I have the certificates in my local store and I need to put them in the Unix server and need to add them to the keytool in Tomcat. How do i do that.
Can I get an example how do I do that with keytool?
There are at least 3 ways of handling this problem:
You can import the certificate into the JRE's default truststore (often in $JAVA_HOME/lib/security/cacerts). This will affect all the applications using that JRE (unless they override the default settings). You'll need to have write permissions on that cacerts file to do this too.
You can import the certificate into a local keystore that you will configure to be Tomcat's default truststore. Typically, you could make a copy of the default cacerts file and import your certificate into this copy, or you can create a new keystore and import only the certificates you know you need (keytool -import -keystore ... will create the keystore file if it doesn't exist). This can be done in tomcat by setting an additional system property in catalina.sh (or .bat): in JAVA_OPTS, you can add -Djavax.net.ssl.trustStore=/path/to/local/truststore.jks for example (and other related properties).
You can make that certificate be used only by certain connections in your application (or set the default SSLContext programmatically). For this, you'll need to alter your application so that it loads the keystore, uses it to initialise a TrustManagerFactory, in passed into an SSLContext. Then, how that SSLContext can be used depends on the client library you're using. There is an example in this answer.
Either way, you can import your cert (be it a CA cert or a specific server cert) into the truststore of your choice using:
keytool -import -file cert.pem -alias "some name" -keystore truststore.jks
(If using the programming route, you can also create your keystore in memory and load the certificate file dynamically, as shown in this answer. Using keystores might be easier, it's up to you to assess the pros and cons of the deployment you want to use.)
I got the answer for this. We need to find which java file the tomcat is using and we need to add the keytool to that particular thing.
this is where the tomcat has its cacerts .ie. the java which is used by the tomcat.
etc/pki/java/cacerts
Keytool command:
keytool -import -alias ttg-lys-cm1 -file /var/lib/certificates/ttg-lys-cm1.cer -keystore "/etc/pki/java/cacerts"
Once you do this restart tomcat and it works fine.
Thanks
pradeepa