My objective is to use keytool to create a certificate signing request (CSR), then take that CSR and make an actual cert to add to the keystore, add it, such that SSL (HTTPS//my.site.com) will work. This is for testing purposes.
So far I have done the following steps:
Generate a keystore for my CSR:
keytool -genkey -dname "CN=test.com, OU=TEST, O=Test, L=TestCity, ST=Florida, C=US" -alias tomcat -keyalg RSA -keysize 2048 -keystore test.keystore -storepass changeit
Generate the CSR:
keytool -certreq -alias tomcat -file request.csr -keystore test.keystore -storepass changeit
Generate a server key to use with openSSL to create a signed cert. This required a password "changeit" and then a conversion to remove the password for the server.key:
openssl genrsa -des3 -out server.key 2048
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
Generate my signed cert using the CSR:
openssl x509 -req -days 365 -in request.csr -signkey server.key -out server.crt
Finally, import the cert into my keystore.
keytool -import -trustcacerts -file server.crt -keystore test.keystore -alias tomcat -storepass changeit
The result is the following error:
keytool error: java.lang.Exception: Public keys in reply and keystore don't match
This does more than generating a key pair, it also generates a self-signed certificate with this DN, which is then used as a basis to generate a CSR with
-certreq
(it may sound odd, but a self-signed cert and a PKCS#10 CSR are actually very similar: the CSR is more or less a self-signed cert without the validity timestamps).This is in the documentation:
What you would normally do when submitting the CSR to a CA is re-import the cert issued by the CA into the same alias (where your private key is), thereby overwriting that temporary self-signed certificate.
You can skip the steps with
keytool -certreq
andopenssl
: simply export the certificate withkeytool
, and re-import it a separate truststore to use with your Java clients if necessary.If you want to simulate a CA,
openssl x509
is not the command you should use:As the documentation for
openssl x509 -signkey
states:So, essentially, the public key material also comes from this private key. Hence, it will not match the public key in the CSR you provided. The CSR is only used to provide the certificate identity information and attributes in this case.
Indeed, turning a CSR into a certificate is something that can have many parameters. While
keytool
generates a reasonable default self-signed certificate from the parameters you provide, OpenSSL generally requires a bit more configuration. For what you're trying to do,openssl ca
would certainly be more relevant, although I would suggest using theCA.pl
wrapper for convenience (it will keep track of the certificates you've issued, serial numbers, and so on).Since this seems to be mainly for testing, possibly on an occasional basis, you may also find other tools like xca to be more convenient to perform that step.
The following procedure describes the creation of a JKS keystore that works perfectly with JBoss 5.0 application server. Tomcat probably uses the same type of keystore.
Create private key and Certificate Signing Request
You can create a private key in a Linux OS with the help of openssl utility.
Set umask to 077 so that the created file is only readable by the current user:
Create a private key of 2048 bits length and store it in file
private_key.pem
:Restore the file creation mask:
You can create a Certificate Signing Request (CSR) with the command:
Next you will have to answer various questions. Give special attention to the Common Name field that must match the Fully Qualified Domain Name of your server. The command generates the following text that comprises the CSR:
Generate a chain certificate
The procedure assumes that you have a (a) private key in file
private_key.pem
, (b) a digital certificate that you have received from a Certificate Authority (CA) in filecertificate.pem
and (c) a chain certificate that certifies the CA in fileca_chain_cert.pem
.In case that your CA is certified by another authority CA1 that is finally certified by a root CA CA_ROOT (CA -> CA1 -> CA_ROOT) and the respective certificates are available in individual files
ca_cert.pem
,ca1_cert.pem
andca_root.pem
respectively, you can create theca_chain_cert.pem
through the command:The chain certificate is generated by combining
certificate.pem
with theca_chain_cert.pem
:The concept is that you must have a file that includes all certificates with the order:
Generate the JKS keystore
This step assumes that file
chain.pem
includes the chain of certificates ,private_key.pem
the private key andcertificate.pem
the server certificate that you received from the CA (first part of the chain).Create a PKCS12 keystore in file
keystore.p12
from the certificate chain and the private key with the following command:Write down the Export password as it will be used in all the following steps to have access to the keystore.
Create a JKS keystore in file
server.keystore
from the PKCS12 keystore:You can list the certificates with the following command:
Verify that the command output states the correct size of the certificate chain. In the case of CA, CA1 and CA_ROOT the size must be 4.
I am not sure the following is right, but it seems to work. Cobbling some steps together from various web sites, executing these commands generate a keystore that works for SSL connections via tomcat. It does it pieces parts which will let me test each piece of my system.