During development, we often use the built-in JDK keytool to create a self-issued certificate and save it to the keystore file. If you want to import a keystore to another keystore (such as installing it on another machine without overwriting files), what should you do?
For example, we import the content with the alias Tomcat from AAA. jks to BBB. jks. The illusion is that the certificate is first exported from AAA. jks and then imported to BBB. jks.
To illustrate the error, we start from scratch. And save the certificate to AAA. jks:
Keytool-keystore AAA. jks-genkey-keyalg RSA-alias Tomcat
Then export the certificate to the tomcat. cert file:
Keytool-keystore AAA. jks-export-file tomcat. cert-alias Tomcat
Import tomcat. Cert to BBB. jks:
Keytool-keystore BBB. jks-import-file tomcat. cert-alias Tomcat
To verify the error, we can use AAA. jks and BBB. jks respectively to start the Tomcat server to see if it can be started successfully. Because we are only for the purpose of verification, we do not need to put the war package file of the application in the Tomcat webapps directory.
Start Tomcat with AAA. jks. Modify the conf \ Server. xml file of Tomcat:
< Connector Port = "8443" Protocol = "Org. Apache. Coyote. http11.http11protocol" Sslenabled = "True" Maxthreads = "150" Scheme = "HTTPS" Secure = "True" Clientauth = "False" Sslprotocol = "TLS" Keystorefile ="AAA. jks" Keystorepass = "Changeit" />
Enter the above AAA. jks as the actual full path name (for example, D: \ AAA. jks ). Start Tomcat. At this time, Tomcat should be able to start successfully.
Close tomcat after confirmation. Next we will replace AAA. jks with BBB. jks, save and restart tomcat. Tomcat will report an exception:
Severe: failed to initialize connector [connector [http/1.1-8443] Org. apache. catalina. lifecycleexception: failed to initialize component [connector [http/1.1-8443] At Org. apache. catalina. util. lifecyclebase. init (lifecyclebase. java: 106) at Org. apache. catalina. core. standardservice. initinternal (standardservice. java: 559) at Org. apache. catalina. util. lifecyclebase. init (lifecyclebase. java: 102) at Org. apache. catalina. core. standardserver. initinternal (standardserver. java: 814) at Org. apache. catalina. util. lifecyclebase. init (lifecyclebase. java: 102) at Org. apache. catalina. startup. catalina. load (Catalina. java: 633) at Org. apache. catalina. startup. catalina. load (Catalina. java: 658) at Sun. reflect. nativemethodaccessorimpl. invoke0 (native method) at Sun. reflect. nativemethodaccessorimpl. invoke (nativemethodaccessorimpl. java: 39) at Sun. reflect. delegatingmethodaccessorimpl. invoke (delegatingmethodaccessorimpl. java: 25) at java. lang. reflect. method. invoke (method. java: 597) at Org. apache. catalina. startup. bootstrap. load (Bootstrap. java: 281) at Org. apache. catalina. startup. bootstrap. main (Bootstrap. java: 450) caused by: Org. apache. catalina. lifecycleexception: protocol handler initialization failed at Org. apache. catalina. connector. connector. initinternal (connector. java: 983) at Org. apache. catalina. util. lifecyclebase. init (lifecyclebase. java: 102 )... 12 morecaused by: Java. io. ioexception: alias name Tomcat does not identify a key entry at org.apache.tomcat.util.net. JSSE. jssesocketfactory. getkeymanagers (jssesocketfactory. java: 567) at org.apache.tomcat.util.net. JSSE. jssesocketfactory. getkeymanagers (jssesocketfactory. java: 505) at org.apache.tomcat.util.net. JSSE. jssesocketfactory. init (jssesocketfactory. java: 449) at org.apache.tomcat.util.net. JSSE. jssesocketfactory. createsocket (jssesocketfactory. java: 158) at org.apache.tomcat.util.net. jioendpoint. BIND (jioendpoint. java: 393) at org.apache.tomcat.util.net. abstractendpoint. init (abstractendpoint. java: 610) at Org. apache. coyote. abstractprotocol. init (abstractprotocol. java: 429) at Org. apache. coyote. http11.20.acthttp11jsseprotocol. init (abstracthttp11jsseprotocol. java: 119) at Org. apache. catalina. connector. connector. initinternal (connector. java: 981 )... 13 more
Why can't I start it with BBB. jks? Therefore, we will check the content in AAA. jks and BBB. jks respectively.
The content in AAA. jks is as follows:
Keytool-keystore AAA.Jks-list-alias Tomcat enter the keystore password: Tomcat, 2012-12-2, privatekeyentry,Authentication fingerprint(MD5): 20: E1: 74: 4b: 0b: 35: 33: FF: Be: 2D: 9d: B5: 31: AB: 3B: De
The content in BBB. jks is as follows:
Keytool-keystore BBB.Jks-list-alias Tomcat enter the keystore password: Tomcat, 2012-12-2, trustedcertentry,Authentication fingerprint(MD5): 20: E1: 74: 4b: 0b: 35: 33: FF: Be: 2D: 9d: B5: 31: AB: 3B: De
The difference is visible from the two outputs above. One is privatekeyentry and the other is trustedcertentry.
In fact, the keystore stores two types of information: private keys and certificates. The certificate contains only public keys. The tomcat. cert file exported above is a certificate file without a private key. Therefore, when we import the data to BBB. jks, only the certificate and the corresponding private key are imported. The server needs to use the private key to communicate with the client's public key, so Tomcat reports the above exception.
So how can we operate it correctly? There are many methods. The most common method is to use the OpenSSL tool instead of keytool to generate certificates and private keys. However, this article only uses keytool.
In fact, the operation is very simple:
Keytool-importkeystore-deststorepass changeit-destkeypass changeit-destkeystore BBB. jks-deststoretype jks-srckeystore AAA. jks-srcstoretype jks-srcstorepass changeit-alias Tomcat
This BBB. jks contains the private key and certificate alias tomcat. If you are not at ease, you can try again by starting tomcat.
The last note is that if the storetype, srcstoretype, and deststoretype parameters are not specified in keytool, the default value is jks.