10

I'm trying to get the certificates just right for our Jira/Confluence deployments in house. People access them differently, either from the hostname or the FQDN. I'm using Java 7's keytool so I have access to the server alternate name functionality:

-ext san=dns:jira

...and I hand it...

jira.example.com

...as the CN when generating the certificate. I then generate a signing request, hand the CSR off to our Win2k8r2 PKI for a certreq to get the key signed and import the key back into the keystore.

Now when I have it setup as I've said above my browsers (Chrome, Firefox, Safari) seem to think the jira is the only valid name even though when I inspect the certificate the CN shows the FQDN.

If I drop the ext it will use the CN which is the FQDN.

When I have multiple ext statements it just uses the last one and I've tried to string multiple DNS:foo under one ext entries together with various punctuation.

Another angle I've run across is to setup the web server to do a 301 to the FQDN. I'm fine with this as well but I'm stuck with Tomcat so "switch to Apache/nginx" won't work for me. This seems to be the only documentation I've come across to do something like that with Tomcat but its 3 years old and it's the end of the day for me. Have they added that functionality to Tomcat6?

kevinarpe
  • 191
  • 10
Tawm
  • 183
  • 1
  • 1
  • 11

4 Answers4

23

I realize this question is pretty old but for anyone who may find it useful I'll mention what works for me:

  • use CN to enter some human friendly name like "our cool JIRA server" ;-)
  • enter san like this: -ext san=dns:jira,dns:jira.example.com

BTW, you can also add IP addresses if you like. I personaly use the following for my development computer:

keytool -certreq ... -file server.csr -keystore server.keystore ... -ext san=dns:localhost,dns:myComputerName,ip:127.0.0.1,ip:::1

NOTE: I use java8 keytool; I hope this works in java7 keytool as well but I haven't tested it

tomorrow
  • 331
  • 2
  • 4
  • 1
    Welcome to ServerFault. It is perfectly fine to answer old question as long as your answer is adding aspects not yet mentioned in other, older answers. Your answer easily meets this requirement. – the-wabbit Feb 24 '16 at 19:05
3

To verify the CSR has the SAN subject alternative names embedded, use the keytool to print the CSR:

keytool -printcertreq -file test.csr

If it worked, you will get something like:

#1: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: test.example.com
  DNSName: test
]

Note -- to get the two entries as above (test.example.com and test), you had to create the CSR as noted in "tomorrow's" answer as "-ext san=dns:test.example.com,dns:test".

Do not follow the misleading keytool documentation [{-ext ext}*] which indicates that zero or more "-ext" entries can be passed in on the command line:

-ext san=dns:test.example.com -ext san=dns:test

This will not work, you will only get the last extension DNS entry (san=dns:test).

DocOc
  • 161
  • 4
2

Generate your multi-domain certificates with OpenSSL and not with keytool then convert key and certificate to a Java Keystore to use with Tomcat. The following example generates a self-signed certificate, it should be easy enough to adapt for a "real" certificate.

Generate an openssl.cnf following the guide in the link above then run these commands:

# Generates a self-signed certificate + key, omit if you already have one
openssl req -config openssl.cnf -x509 -days 3650 -newkey rsa:2048 \
   -out self-signed-certificate.pem -keyout pub-sec-key.pem
# Remove passphrase from key
openssl rsa -in pub-sec-key.pem -out new.key
# Generate PKCS12 keystore
openssl pkcs12 -export -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES \
   -export -in self-signed-certificate.pem -inkey new.key -name alias \
   -out keystore.p12
# Convert PKCS12 to JKS
keytool -importkeystore -destkeystore keystore.jks -deststoretype JKS \
   -srcstoretype PKCS12 -srckeystore keystore.p12

Pay attention to the alias value to -name in the above example. That's the name of the certificate you have to pass to tomcat.

For the sake of completion, I'll include how issuing a certificate with SANs may work with a Certificate Authority:

SAN                     = email:copy

...

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName=${ENV::SAN}
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

Run this command to generate a Key + CSR containing SANs (untested):

SAN="DNS: domain1.example.com, DNS: domain2.example.com" openssl req \
   -config /path/to/openssl.conf \
   -subj "/C=XX/ST=XX/L=xxx/O=My Org/OU=My OU/CN=main.example.com" \
   -newkey rsa:2048 -out file.csr -keyout out.key \
   -infiles /path/to/csr/file.csr

Run this command to issue a certificate:

SAN="DNS: domain1.example.com, DNS: domain2.example.com" openssl ca \
   -config /path/to/openssl.conf -policy policy_anything \
   -subj "/C=XX/ST=XX/L=xxx/O=My Org/OU=My OU/CN=main.example.com" \
   -infiles /path/to/csr/file.csr
fuero
  • 9,413
  • 1
  • 35
  • 40
  • I tried this and I get a certificate in a java keystore but when I do a certreq it doesn't have any of the SANs attached to it. – Tawm Mar 26 '13 at 21:21
  • You are not supposed to use `keytool` to generate a CSR in this approach. You do all the certificate wrangling with `OpenSSL` and just convert its result to a Java keystore to use with tomcat. – fuero Mar 31 '13 at 15:33
-3

For multiple SAN entries the correct command line for keytool would be:

-ext san=dns:test.example.com,dns:test
Gerald Schneider
  • 19,757
  • 8
  • 52
  • 79
Totyu
  • 1