keytool enhancements

Update: CRLDistributionPoints extension support added.
There're two enhancements made to keytool today (the doc has not been updated, it's still for JDK 6):

new commands and options

We have 2 new commands: -gencert, -printcertreq and 1 new option -ext. Read the RFE descriptions.

-printcertreq is simply for printing the content of a certificate request. It behaves like the -printcert command, reading a PKCS #10 format cert req from a file or stdin, and does not need a keystore to run with.

-gencert is a big enhancement, which means you can setup a tiny CA now with keytool. The command reads a certificate request from a file (specified by -infile) or stdin, creates a certificate, signs it with the private key in the PrivateKeyEntry specified by -alias, and print the output to another file (specified by -outfile) or stdout. That's it. Just like -genkeypair for self-signed certificate, you can specify -sigalg, -startdate, and -validity options to the command.

-ext is used to add X.509v3 certificate extensions to a certificate (for both -genkeypair and -gencert) or a certificate request (for -certreq). The option can be specified multiple times to add multiple extensions. The value of this option takes the form of name[:critical][=value]. Here name is the extension name, and value the value (omit if empty). The :critical modifier, if provided, means the extension's isCritical attribute is true; otherwise, false.

Currently we support these named extensions (case-insensitive):
BC or BasicConstraintsThe full form: "ca:{true|false}[,pathlen:len]"; or, "len", a shorthand for "ca:true,pathlen:len"; or omitted, means "ca:true"
KU or KeyUsageusage(,usage)\*, usage can be one of digitalSignature, nonRepudiation (contentCommitment), keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly. Usage can be abbreviated with the first few letters (say, dig for digitalSignature) or in camel-case style (say, dS for digitalSignature, cRLS for cRLSign), as long as no ambiguity is found. Usage is case-insensitive.
EKU or ExtendedkeyUsageusage(,usage)\*, usage can be one of anyExtendedKeyUsage, serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, OCSPSigning, or any OID string. Named usage can be abbreviated with the first few letters or in camel-case style, as long as no ambiguity is found. Usage is case-insensitive.
SAN or SubjectAlternativeNametype:value(,type:value)\*, type can be EMAIL, URI, DNS, IP, or OID, value is the string format value for the type.
IAN or IssuerAlternativeNamesame as SubjectAlternativeName
SIA or SubjectInfoAccessmethod:location-type:location-value (,method:location-type:location-value)\*, method can be "timeStamping", "caRepository" or any OID. location-type and location-value can be any type:value supported by the SubjectAlternativeName extension.
AIA or AuthorityInfoAccesssame as SubjectInfoAccess. method can be "ocsp", "caIssuers" or any OID.
CRL or CRLDistributionPointssame as SAN. This means you can only add one point with only names

When name is an arbitrary OID, value is the HEX dumped DER encoding of the extnValue for the extension excluding the OCTET STRING type and length bytes. Any extra character other than standard HEX numbers (0-9, a-f, A-F) are ignored in the HEX string. Therefore, both "01:02:03:04" and "01020304" are accepted as identical values. If there's no value, the extension has an empty value field then.

A special name "honored", used in -gencert only, denotes how the extensions included in the certificate request should be honored. The value for this name is a comma-seperated list of "all" (all requested extensions are honored), "name[:{critical|non-critical}]" (the named extension is honored, but using a different isCritical attribute) and "-name" (used with all, denotes an exception). Requested extensions are not honored by default.

If, besides the -ext honored option, another named or OID -ext option is provided, this extension will be added to those already honored. However, if this name (or OID) also appears in the honored value, its value and criticality overrides the one in the request.

The subjectKeyIdentifier extension is always created. For non self-signed certificates, the authorityKeyIdentifier is always created.

Try this command on your system if you already have 2 self-signed certs me and ca created in your default keystore:
    keytool -storepass changeit -certreq -alias me -ext bc -ext eku=sa,ca | \\
    keytool -storepass changeit -gencert -alias ca -ext honored=all,-bc \\
        -ext aia=ocsp:uri:,cai:uri:  |
    keytool -printcert
Here, the user me requests for an SSL server certificate from the CA. It asks for an EKU extension named ServerAuth and ClientAuth, which is useful for an SSL server. However, it also secretly asks for a BC extension, so that it can start its own CA. The CA, with sharp eyes, notices this problem. It grants all extensions requested except BC. It also adds another extension AIA which includes issuer info into the cert generated.

openssl-style certificate support

When you run openssl x509 -text with an X.509 certificate, the output includes a bunch of human-readable texts before the BASE64-encoded certificate itself. Java did not accept these texts and threw an exception something like "unknown tag or bad length", since it tried to interpret the file as DER encoded. Now we enhance the X.509 CertificateFactory class to accept this kind of certificate.

By the way, have I mentioned -startdate before? This option allows you to change the issuing time of a certificate from current system time to something else. Some people may like this option to create certs for special test cases, and some other people would like the certificate to have an earlier time because they want to use it right now but their clients and servers are not precisely time-synchronized. The grammar for this option takes one of the 2 following formats:
  1. ([+-]nnn[ymdHMS])+
  2. [yyyy/mm/dd] [HH:MM:SS]
So -startdate -5M means 5 minutes ago, -startdate "2001/01/01 11:11:11" means that exact time, -startdate 11:11:11 means that time today. Read more in the RFE decriptions.

These are really great news!

Just one question, the description of the RFE states that -ext has been implemented for Java 7, and not for Java 6 as you say. Does this mean that it has been back-ported to Java6 and will be available at some update?


Posted by Rodrigo Ruiz on March 10, 2009 at 04:41 PM CST #

Hello Weijun,
From your post, it means that adding DNS names extensions as Certificate Subject Alt Name for X509v3 is not possible in JDK 6 (and previous versions) but it'll be with JDK 7 which implements the -ext option. Correct?

Posted by SALAUN on October 23, 2009 at 03:14 PM CST #

It's now in JDK 7 (and OpenJDK), not in JDK 6 or any other previous releases.

Posted by Weijun on October 24, 2009 at 12:29 PM CST #

Many thanks for your answer Weijun!

Posted by Gildas on October 26, 2009 at 09:25 AM CST #


I'm trying to create a csr with SAn domain but i get error, I'm using:

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -dname ", OU=internal, O=myown, L=Berkeley, S=California, C=US" -ext ",," -keystore keystore.jks

Posted by David on March 21, 2011 at 05:18 AM CST #

@David. You command executes perfectly fine on my system with the latest JDK 7 build. What error are you seeing? Please add "-debug" option for a verbose debug output.

Also, can you tell me what build and OS you're using?

Posted by Weijun on March 21, 2011 at 06:41 AM CST #

Hello Weiju,

Thanks for your reply, I have installed the jdk 7 Build b134 from

My OS is windows 7 32 bits... Any idea? I will try with -debug

Posted by David on March 21, 2011 at 07:22 AM CST #


I have reisntalled the jdk, and works the command but when I decode the csr Does not include the san values...

Please help me

Posted by David on March 21, 2011 at 07:30 AM CST #

I tried it on a Windows XP 32 bits and it works.

Just run "keytool -list -v" and you will see the sAN values.

What do you mean csr? Are you creating a certificate request? If so, you need to add the "-ext ..." options to the "keytool -certreq" command also. Then, you can see the sAN values are there from the "keytool -printcertreq" command.

Posted by Weijun on March 21, 2011 at 07:40 AM CST #

Hello Weijun,

Thank you very much for your interest in helping!!!

I have tried again and works, but I have a question, if I have already generated a keypair with san domains and i just use -certreq the csr does not contain the san domains, (I need to generate the csr with the command -ext "SAN=DNS:....)

I any way to fix this?....

Other hand can I generate a keypair with the san domains and in one step generate the csr?

Posted by David on March 21, 2011 at 07:03 PM CST #

Sorry, we don't have such an option now, you need to type in the options again at -certreq.

Posted by Weijun on March 22, 2011 at 03:28 AM CST #

Weijun, thank you very much for your help!! you're very helpful.

Posted by David on March 23, 2011 at 04:12 AM CST #

Hi, Can someone tell me in a example how to add the custom OID() extension without a valueto the OID to the certificate signing request which i am using now like

keytool -certreq -alias server -keystore keystore -ext ??

lets say

in my certificate i just want to check the presence of this OID so i dont need a value associated with it.

Posted by guest on May 10, 2012 at 11:24 AM CST #

Someone knows how to edit fiels on a csr, for example the cn, my certification authority can do that...

Posted by Daniel on May 10, 2012 at 11:57 AM CST #

@Daniel: I guess you can just add "-ext" to your command, is that what you need?
What do you mean edit fields inside a csr? You can create a new csr but cannot edit one. A csr has a signature and if you edit it the signature will be invalidated. Or do you mean a CA can issue you a cert that has different field values from your csr? You can always provide new options to the -gencert command to override the one in csr. For example, a new -dname, a new -ext, etc.

Posted by guest on May 10, 2012 at 12:12 PM CST #

Thanks guest, I mean that a CA can issue my cert with different fields from my csr, so the're editing the csr?

Please explain me this...

About the -gencert how that works? What else can I do with this command?

Posted by Daniel on May 10, 2012 at 12:20 PM CST #

They aren't editing your csr, they just issue you a cert with different fields from your request.

-gencert is the keytool command for you to act as a CA. Read the JDK 7 doc or this blogpost. In your case, you can

keytool -keystore myks -genkaypair -alias me -dname="CN=Me"
keytool -keystore myks -certreq > csr

and if the CA is also using keytool, he can

keytool -gencert -infile csr -alias ca -dname "CN=You"

to issue you a cert. Here you can see that he modified your dname.

Posted by weijun on May 10, 2012 at 12:28 PM CST #

Hello weijun,

Thaks so much, I'll try with your command.

Posted by Daniel on May 12, 2012 at 09:47 AM CST #

Ok, keytool -ext question,can you show a sample -ext entry to store the CRL url in extensions

Posted by guest on January 05, 2013 at 04:11 AM CST #

CRLDistributionPoints is already supported by keytool directly, so you can simply use -ext crl=uri:

Posted by guest on January 05, 2013 at 10:55 AM CST #

Post a Comment:
  • HTML Syntax: NOT allowed

This blog has a comments managing system that requires me to approve each comment manually. Please do not re-post and I will reply it (if I have an answer) when I get pinged.


Top Tags
« April 2014