158

I need to import a certificate into my JVM keystore. I am using the following:

keytool -import -alias daldap -file somecert.cer

so I would need to probably change my call into something like:

keytool -import -alias daldap -file somecert.cer -keystore cacerts –storepass changeit
Strong Like Bull
  • 11,155
  • 36
  • 98
  • 169
  • 2
    You need to import a certificate into your JVM *truststore,* unless its a signed CSR, in which case you should be importing it into your *own* keystore, and you must already know where that is, otherwise you wouldn't have been able to generate the keypair or the CSR. – user207421 Aug 29 '14 at 06:39

10 Answers10

159

Your keystore will be in your JAVA_HOME---> JRE -->lib---> security--> cacerts. You need to check where your JAVA_HOME is configured, possibly one of these places,

  1. Computer--->Advanced --> Environment variables---> JAVA_HOME

  2. Your server startup batch files.

In your import command -keystore cacerts (give full path to the above JRE here instead of just saying cacerts).

kosa
  • 65,990
  • 13
  • 130
  • 167
49

Keystore Location

Each keytool command has a -keystore option for specifying the name and location of the persistent keystore file for the keystore managed by keytool. The keystore is by default stored in a file named .keystore in the user's home directory, as determined by the "user.home" system property. Given user name uName, the "user.home" property value defaults to

C:\Users\uName on Windows 7 systems
C:\Winnt\Profiles\uName on multi-user Windows NT systems
C:\Windows\Profiles\uName on multi-user Windows 95 systems
C:\Windows on single-user Windows 95 systems

Thus, if the user name is "cathy", "user.home" defaults to

C:\Users\cathy on Windows 7 systems
C:\Winnt\Profiles\cathy on multi-user Windows NT systems
C:\Windows\Profiles\cathy on multi-user Windows 95 systems

https://docs.oracle.com/en/java/javase/17/docs/specs/man/keytool.html#importing-a-certificate-for-the-ca

dbrin
  • 15,525
  • 4
  • 56
  • 83
  • 3
    I've been searching for this mystery `~/.keystore` file! If I left off the `-keystore` parameter, I couldn't figure out which default keystore `keytool` targeting. I kept looking for other `cacerts` somewhere else on the machine. I didn't expect keytool to generate `~/.keystore` in the home directory, nor for it to be named `.keystore` instead of `cacerts`. You've filled in a blank that the Java folks should document! Thank you! – George Pantazes Dec 13 '18 at 22:40
30

Mac OS X 10.12 with Java 1.8:

$JAVA_HOME/jre/lib/security

cd $JAVA_HOME

/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home

From there it's in:

./jre/lib/security

I have a cacerts keystore in there.

To specify this as a VM option:

-Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit

I'm not saying this is the correct way (Why doesn't java know to look within JAVA_HOME?), but this is what I had to do to get it working.

atlas_scoffed
  • 3,542
  • 30
  • 46
24

You can find it in your "Home" directory:

On Windows 7:

C:\Users\<YOUR_ACCOUNT>\.keystore

On Linux (Ubuntu):

/home/<YOUR_ACCOUNT>/.keystore
Diptangsu Goswami
  • 5,554
  • 3
  • 25
  • 36
Evans Y.
  • 4,209
  • 6
  • 35
  • 43
18

This works for me:

#! /bin/bash

CACERTS=$(readlink -e $(dirname $(readlink -e $(which keytool)))/../lib/security/cacerts)

if keytool -list -keystore $CACERTS -storepass changeit > /dev/null ; then
    echo $CACERTS
else
    echo 'Can not find cacerts file.' >&2
    exit 1
fi

Only for Linux. My Solaris has no readlink. In the end I used this Perl-Script:

#! /usr/bin/env perl
use strict;
use warnings;
use Cwd qw(realpath);
$_ = realpath((grep {-x && -f} map {"$_/keytool"} split(':', $ENV{PATH}))[0]);
die "Can not find keytool" unless defined $_;
my $keytool = $_;
print "Using '$keytool'.\n";
s/keytool$//;
$_ = realpath($_ . '../lib/security/cacerts');
die "Can not find cacerts" unless -f $_;
my $cacerts = $_;
print "Importing into '$cacerts'.\n";
`$keytool -list -keystore "$cacerts" -storepass changeit`;
die "Can not read key container" unless $? == 0;
exit if $ARGV[0] eq '-d';
foreach (@ARGV) {
    my $cert = $_;
    s/\.[^.]+$//;
    my $alias = $_;
    print "Importing '$cert' as '$alias'.\n";
    `keytool -importcert -file "$cert" -alias "$alias" -keystore "$cacerts" -storepass changeit`;
    warn "Can not import certificate: $?" unless $? == 0;
}
ceving
  • 21,900
  • 13
  • 104
  • 178
11

On Debian, using openjdk version "1.8.0_212", I found cacerts here:

 /etc/ssl/certs/java/cacerts

Sure would be handy if there was a standard command that would print out this path.

Patrick Beard
  • 592
  • 6
  • 11
7

As DimtryB mentioned, by default the keystore is under the user directory. But if you are trying to update the cacerts file, so that the JVM can pick the keys, then you will have to update the cacerts file under jre/lib/security. You can also view the keys by executing the command keytool -list -keystore cacerts to see if your certificate is added.

MADHAIYAN M
  • 2,028
  • 25
  • 22
Sharan Rajendran
  • 3,549
  • 2
  • 19
  • 6
  • Nice to know that the keytool command adds the correct `lib/security` path automatically if given only the relative name. – ceving Dec 05 '12 at 13:58
  • 2
    But this will not work for `-importcert`. The list command shows the system wide certificates but the import command generates a new file in the current directory. – ceving Dec 05 '12 at 14:14
  • 1
    `updatedb; locate cacerts` helps for finding where the install locations of th e cacerts files are. – sjas Mar 26 '15 at 11:17
5

For me using the official OpenJDK 12 Docker image, the location of the Java keystore was:

/usr/java/openjdk-12/lib/security/cacerts
jonashackt
  • 12,022
  • 5
  • 67
  • 124
  • 3
    That's a truststore, not a keystore. – user207421 Aug 28 '19 at 09:04
  • 3
    First: If you read the question carefully (and your own comment), it sounds more like a Truststore, where a cert should be imported. Second, the difference between the Truststore and Keystore is quite disorienting - and both use the term "Keystore" btw, since they use the format both. Third: If you have a look at the import command `keytool -import -file example.crt -alias exampleCA -keystore truststore.jks` you also use the parameter `-keystore`... quite unclear IMHO. And last but not least: I was searching about that exact problem - and found that so question. Maybe others exp the same. – jonashackt Oct 02 '19 at 12:05
  • Furthermore all other answers also refer to the so called "Truststore" the JDK uses to validate. So did you also downvote all the other answers as well? I already received an upvote, so there's already somebody my answer helped out. – jonashackt Oct 02 '19 at 12:11
0

We encountered this issue on a Tomcat running from a jre directory that was (almost fully) removed after an automatic jre update, so that the running jre could no longer find jre.../lib/security/cacerts because it no longer existed.

Restarting Tomcat (after changing the configuration to run from the different jre location) fixed the problem.

0

In addition to all answers above:

If updating the cacerts file in JRE directory doesn't help, try to update it in JDK.

C:\Program Files\Java\jdk1.8.0_192\jre\lib\security

VSh
  • 438
  • 4
  • 13