2

My question is similar to this one: Tomcat fails to find a key entry in keystore

I have a CER file, which I had imported into a JKS using the below command:

keytool -importcert -file codesign_Base64.cer -keystore imported_keystore.jks -alias my_alias

Then I have the below line of configuration in standalone.xml for the jBoss.

<subsystem xmlns="urn:jboss:domain:web:1.1" native="false" default-virtual-server="default-host">
            <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" redirect-port="8443"/>
            <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
                <ssl name="ssl" key-alias="my_alias " password="change_this" certificate-key-file="C:\Programs\Siemens\JBoss7.1.0\domain\configuration\imported_keystore.jks " protocol="TLSv1" verify-client="false"/>
            </connector>
            <virtual-server name="default-host" enable-welcome-root="false">
                <alias name="localhost"/>
                <alias name="example.com"/>
            </virtual-server>
        </subsystem>

With this, when I try to launch the application, I see the following error messages in the jBoss log files which depicts an error of this sort.

11:46:19,692 ERROR [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-4) Error initializing endpoint: java.io.IOException: Alias name mykey does not identify a key entry
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:517) [jbossweb-7.0.10.Final.jar:]
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:452) [jbossweb-7.0.10.Final.jar:]
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:168) [jbossweb-7.0.10.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:977) [jbossweb-7.0.10.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:190) [jbossweb-7.0.10.Final.jar:]
    at org.apache.catalina.connector.Connector.init(Connector.java:983) [jbossweb-7.0.10.Final.jar:]
    at org.jboss.as.web.WebConnectorService.start(WebConnectorService.java:267) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_75]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]

But if I explore the contents of the java key store, I still get to see the presence of the appropriate key.

C:\Programs\Siemens\JBoss7.1.0\domain\configuration>keytool -list -keystore C:\Programs\Siemens\JBoss7.1.0\domain\configuration\winstore.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

my_alias, Jun 23, 2017, trustedCertEntry,
Certificate fingerprint (SHA1): 8D:64:10:8B:F6:0D:1E:17:01:52:1C:97:8A:89:75:80:2D:2F:45:6B

I have run into the similar problem when I tried with a P7B certificate also. The only thing that worked out till now was if the certificate was generated manually - selftsigned certificate. And this is not the go forward strategy for the organization obviously

Please let me know what could be missing here. The similar post which I had included above seems to be hinting at a certificate-only-and-not-key scenario which I am unable to related.

Any pointers would surely help as I have posted this in multiple places and I am not having any responses at the moment.

Thanks, Pavan.

1 Answers1

3

No, your keystore does NOT contain a privatekey. See where it says trustedCertEntry? A trusted certificate is NOT a privatekey, it is only a certificate, and a certificate is not a privatekey. An SSL/TLS server requires a privatekey AND the matching certificate chain; a certificate alone cannot be used to execute the protocol so your server cannot accept any HTTPS connections and thus any browser that tries to connect with HTTPS (likely after being redirected from HTTPS) fails. A P7B doesn't contain a privatekey either, although it can contain mutiple certificates while a CER normally contains only one. (In contrast, a client usually needs only the CA 'root' cert(s), and no privatekey, unless the fairly rare 'client authentication' option is used.)

You need a privateKeyEntry which contains both the privatekey AND a certificate chain for that key and your desired hostname(s). There are two ways (with a variant) to do this for Java:

1: Use keytool to generate a new privatekey (with dummy self-signed cert) in a JKS and create a CSR (Certificate Signing Request, or just Cert[ificate] Req[uest]) for it. Submit the CSR and other things as needed such as payment to a Certificate Authority (CA) to obtain a suitable certificate, usually accompanied by at least one 'chain' or 'intermediate' cert that may be needed for clients to trust the cert. Use keytool to import the certificate/chain into the same JKS and entry that already contains the privatekey (replacing the dummy self-signed cert); optionally you can also import the chain cert(s) as trustedcert entries.

Method 1 is canonical and is described, usually repeatedly, on the website of every cert supplier I've ever looked at, both CAs and resellers; I don't know how you missed them all. Note these descriptions often refer to Tomcat, the most widely-used Java-based webserver; the Jboss webserver component, now branded Wildfly, is actually a fork of Tomcat. Here are the first two google finds me:
* https://www.digicert.com/csr-creation-java.htm
* https://knowledge.symantec.com/support/ssl-certificates-support/index?page=content&id=INFO227

2A: Use other tools (like Windows or MacOS or OpenSSL) to generate a privatekey, and obtain a suitable certificate, typically using a CSR, from a CA and including its chain. As applicable, export/convert/combine the privatekey AND certificate chain into a PKCS12 file (also called PFX in Microsoft-land), and probably then use keytool -importkeystore to convert the PKCS12 to JKS. (In Java 8 in many cases you can actually use a PKCS12 directly, without converting it to JKS, and Java 9 is expected to encourage this.)

2B: If you already have a privatekey generated and suitable certificate/chain obtained with other tools, just put them in a PKCS12 and probably convert to JKS as above.

Note that some other GUIs like Microsoft, MacOS, and Firefox focus on the certificate: they display a trusted-other certificate as just 'certificate', and a privatekey plus certificate combination as 'certificate with privatekey'. But the difference is still vital; a server must have the privatekey and trying to use a 'certificate without privatekey' fails. Java instead has different types of keystore entries -- although for some keystores these types are not actually stored directly.

dave_thompson_085
  • 3,262
  • 1
  • 16
  • 16