本ページはプロモーションが含まれています

Java入門

【2026年版】Javaのcacerts確認方法|読み方・場所・keytoolコマンドを3分で解説

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

Javaで「unable to find valid certification path」「PKIX path building failed」が出て、開発が止まっていませんか。

原因の9割は「Javaが見ているcacertsに証明書が入っていない」か「使っているjava.homeを取り違えている」のどちらかです。

ちなみに「cacerts」は「シーエーサーツ」または「カサーツ」と読みます(Certificate Authority certificatesの略で、正式な読み方が定められているわけではなく、現場では英語表記のまま「シーエーサーツ」と呼ばれることが最も多いです)。

読み方が気になっただけの方はここで解決ですが、実際にエラーに直面している方はこのまま読み進めてください。

結論から言うと、cacertsの場所さえ特定できれば、あとはkeytool -listコマンド1行で証明書の有無を確認できます

エラーの9割はcacertsの場所を取り違えているか、証明書が未登録のどちらかです。

この記事でわかること

  • keytoolコマンドでcacertsの証明書一覧を確認する方法
  • cacertsファイルの場所(Windows/macOS/Linux、Java25対応)
  • 「PKIX path building failed」などエラーの原因と対処法

この記事では、keytoolでルート証明書一覧を確認する3つのコマンドと、Java8/Java11以降で配置場所が異なるcacertsのパス(Windows・macOS・Linux別)を、コピペで使える形で整理しました。

さらに、-Djavax.net.ssl.trustStoreで別キーストアを指定している場合の判別方法、自己署名証明書をimportcertで追加する手順、削除時の注意点まで、SSLエラー対処に必要な操作を一通り網羅しています。

私は新人時代に証明書エラーで丸1日を溶かしましたが、ここに書いた手順を最初から知っていれば10分で解決していました。

同じ時間を消耗しないよう、まずは現在使われているjava.homeの確認コマンドからお試しください。

そもそもJavaのルート証明書とは?cacertsとkeytoolの関係を3分で理解

Javaのルート証明書とcacerts・keytoolの関係を示す図解

cacertsとは、Javaが標準で信頼するルート証明書をまとめて格納しているキーストアファイルのことです。

ファイル形式はJava8まではJKS、Java9以降はPKCS12が標準となっています。

Javaのルート証明書は、ざっくり言うと「この相手なら信じていいよ」とJavaが判断するための“信用リスト”みたいなものです。

私たちがブラウザで普通にネットショッピングできるのも、裏で「このサイト、本物?」と確認してくれているから。

それと同じことをJavaプログラムもやっています。

HTTPSで通信するときは、サーバーから証明書が送られてきます。

Javaはそれをチェックして、「この証明書って、信頼できる発行元が出したやつ?」と、自分が持っている“信用リスト”と照らし合わせます。

この仕組みを知っておくと、通信でエラーが出たときに「証明書の問題かな?」と当たりをつけやすくなるので、トラブル対応がぐっと楽になります。

ルート証明書の役割|信頼チェーンの起点とは

ルート証明書は、信頼の連鎖(チェーン)の起点となる最上位の証明書です。

Javaはこのルート証明書をあらかじめ保持しているため、初めて通信するサーバーでも安全に接続できます。

もし存在しなければ、接続のたびに手動で信頼確認が必要になり、プログラムによる自動処理は実現できません。

イメージしやすいように、現実で例えると“パスポートを発行する国”が近いです。

私たちが誰かの身分証明を信じられるのは、その人のパスポート(=サーバー証明書)が、ちゃんと信用できる国(=ルート認証局)によって発行されているからですよね。

Javaは最初から「信用できる国リスト」を持っていて、その国が発行した“パスポート”だけ通信を許可する仕組みです。

だからこそ、知らないサーバー相手でも安全に通信できるというわけです。

中間証明書との違い|PKIエラーが起きる仕組み

中間証明書は、ルート証明書とサーバー証明書の間をつなぐ役割を持っています。

ルート証明書の秘密鍵が漏洩すると影響が甚大です。そのためルート認証局はオフラインで厳重に保管され、直接署名には使いません。

代わりに、中間認証局に署名権限を委譲しています。一般的な証明書の構成は以下のようになります。

  1. ルート証明書(Javaが元々持っている)
  2. 中間証明書(サーバーから送られてくることが多い)
  3. サーバー証明書(通信したいサーバーのもの)

トラブルが起きる際、Java側にルート証明書がないケースもあれば、サーバー側が中間証明書を送り忘れているケースもあります。

この違いを理解しておくと、自分の環境を直すべきか、相手に設定修正を依頼すべきかの判断が早くなります。

Javaにおける証明書管理の全体像(JRE・JDK・keytool)

Javaでは、証明書はOSの機能ではなく、Java独自の「キーストア」という仕組みで管理されています。

WindowsやmacOSにも証明書を管理する機能はありますが、Javaはそれらを直接参照しません。

Javaのインストールディレクトリ内にある特定のファイル(キーストア)だけを見ています。

管理に使われる主な要素は以下の3つです。

  • cacertsファイル:ルート証明書が格納されているデータベースファイル
  • keytool:証明書を追加・削除・確認するためのコマンドラインツール
  • JRE/JDK:これらがインストールされたフォルダの中に上記が含まれる

つまり、Javaの証明書問題に対処するには、OSの設定画面を開くのではなく、Javaフォルダ内のファイルを確認しなければなりません。

keytoolでできることの全体像|証明書の確認以外の主な使い道

この記事ではcacertsの確認に絞って解説していますが、keytool自体は証明書の確認だけでなく、鍵ペアの生成やCSR発行までこなせる多機能なコマンドです。

「確認だけしたい」なら本記事の-list-printcertだけで十分ですが、他の場面で目にするコマンドも簡単に紹介しておきます。

  • -genkeypair:自己署名証明書と公開鍵・秘密鍵のペアを新規作成する
  • -certreq:認証局(CA)に提出するCSR(証明書署名要求)を発行する
  • -exportcert:キーストア内の証明書を単体の証明書ファイルとしてエクスポートする

証明書エラーの調査でkeytoolを使うのはほぼ-list-printcert-importcert-deleteの4つに絞られますが、サーバー証明書を自分で発行・更新する立場になったときは上記3コマンドも合わせて覚えておくと迷いません。

Javaのルート証明書を確認する3つの方法【keytool・SSLContext・java.home】

Javaのルート証明書を確認する3つの方法を示す図解

Javaのルート証明書を確認するには、keytoolというコマンドを使用します。

Javaの証明書ストアはバイナリ形式のファイルであり、テキストエディタで開いても中身を解読できないからです。

ターミナルやコマンドプロンプトを開き、専用のコマンドを打ち込むことで、現在登録されている証明書の一覧や有効期限を表示させることができます。

正しいコマンドと対象ファイルの場所さえわかれば、確認作業は非常にシンプルです。

keytoolコマンドで証明書一覧を確認する手順(-list オプション)

証明書の一覧を表示するには、以下のコマンドを使用します。

keytool -list -keystore "cacertsファイルのパス" -storepass changeit

ここで重要なのがパスワードです。

Javaのキーストアのデフォルトパスワードは「changeit」です(2025年9月リリースの現行LTS・Java25時点でも変更されていません)。

直訳すると「これを変えろ」という意味ですが、多くの環境ではそのまま使われており、UbuntuやRHELのca-certificates-javaパッケージでも踏襲されています。

もし詳細な情報(有効期限や署名アルゴリズムなど)が見たい場合は、-v(verbose)オプションを追加します。

keytool -list -v -keystore "cacertsファイルのパス" -storepass changeit

これで、登録されているすべての証明書がずらりと表示されます。

特定の証明書を探したいときは、Windowsならfindstr、MacやLinuxならgrepコマンドと組み合わせると便利です。

実行すると、以下のような形式で証明書が一覧表示されます(-vなしの場合の出力例)。

キーストアのタイプ: PKCS12
キーストア・プロバイダ: SUN

キーストアには158個のエントリが含まれます

digicertglobalrootg2, 2021/05/13, trustedCertEntry,
証明書のフィンガプリント (SHA-256): CB:3C:CB:B7:60:31:E5:E0:...
isrgrootx1 [jdk], 2023/12/05, trustedCertEntry,
証明書のフィンガプリント (SHA-256): 96:BC:EC:06:26:49:76:F3:...

「エントリが含まれます」の件数(この例では158件)は、Javaのバージョンやディストリビューションによって前後します。

目的の証明書を探すときは、エイリアス名(1行目のisrgrootx1のような部分)でgrepfindstrすると早いです。

cacerts内の証明書の中身(Subject/Issuer/有効期限)を1コマンドで読む方法

キーストア全体を一覧するのではなく、特定の証明書ファイル(.cer.pem)の中身だけを確認したいときは、keytool -printcert が便利です。

keytool -printcert -file server.cer

これだけで Owner(Subject)・IssuerValid fromValid until・SHA-256フィンガープリントが表示されます。

フィンガープリントは公式サイトの値と照合するためにも必須です。

リモートサーバーの証明書を取得して中身を見たい場合は、openssl s_client と組み合わせるのが定番です。

openssl s_client -connect example.com:443 -showcerts < /dev/null | openssl x509 -outform DER > server.cer
keytool -printcert -file server.cer

「証明書をブラウザでエクスポートする」のではなく、ターミナルだけで完結するため、サーバー上で確認するときに重宝します。

cacertsファイルの場所(Windows / macOS / Linux)

cacertsファイルは、Javaのバージョンによって格納場所が微妙に異なります。

Java8以前と、Java9以降でフォルダ構成が変わったためです。ここを間違えると「ファイルが見つかりません」というエラーになります。

以下に代表的なOSとバージョンの組み合わせごとのパスを示します。

Windows10 / Windows11 の場合

  • Java8以前: C:\Program Files\Java\jdk1.8.0_xx\jre\lib\security\cacerts
  • Java11以降(Java17/Java21/Java25 LTS): C:\Program Files\Java\jdk-25\lib\security\cacerts(2025年9月リリースのJava25が現行LTS。Java21なら jdk-21、Java17なら jdk-17、Java11なら jdk-11

macOS の場合

  • Java8以前: /Library/Java/JavaVirtualMachines/jdk1.8.0_xx.jdk/Contents/Home/jre/lib/security/cacerts
  • Java11以降(Java17/Java21/Java25 LTS): /Library/Java/JavaVirtualMachines/jdk-25.jdk/Contents/Home/lib/security/cacerts(現行LTSのJava25。Java21なら jdk-21.jdk、Java17なら jdk-17.jdk

Linux (RHEL / Ubuntuなど) の場合

  • 多くのディストリビューションでは、/etc/pki/java/cacerts/usr/lib/jvm/java-xx-openjdk/lib/security/cacerts にシンボリックリンクが貼られていることが多いです。

Java9以降はJEP 220(Modular Run-Time Images)により独立したJREディストリビューションが廃止され、jreフォルダが消えました。

そのためcacerts$JAVA_HOME/lib/security/cacertsに直接配置されます。

このjreフォルダ廃止という配置場所の変更を覚えておくと迷わずに済みます。

使用中のJavaが参照しているキーストアを調べる方法

複数のJavaがインストールされている環境では、どのcacertsを見ているか確認が必要です。

環境変数JAVA_HOMEの設定と、実際に動いているjavaコマンドのパスが異なっていることがよくあるからです。

もっとも確実なのは、以下のコマンドで現在アクティブなJavaのホームディレクトリを表示させることです。

java -XshowSettings:properties -version 2>&1 | findstr "java.home"

※ Mac/Linuxの場合は findstrgrep に置き換えてください。

ここで表示されたパスの下にある lib/security/cacerts (または jre/lib/security/cacerts)が、現在使われている正解のファイルです。

ここを確認せずに作業をすると、「証明書を追加したのに反映されない」というトラブルに直面します。

あわせて読む
あわせて読む

証明書の有効期限を確認する方法(keytool -list -v)

ルート証明書は永久に有効ではありません。

多くは10〜20年で期限切れとなり、ある日突然「TLSハンドシェイクが失敗するようになった」というトラブルの原因になります。

cacerts内の各証明書の有効期限を確認するには、-v オプションを付けて一覧します。

# macOS / Linux
keytool -list -v -keystore "$JAVA_HOME/lib/security/cacerts" -storepass changeit | grep -E "Alias name|Valid"

これで Alias name: ...Valid from: ... until: ... がペアで表示されます。

「2026年内に切れる証明書」だけ抽出したい場合は、後続のスクリプトで until: ... 2026 を grep するのが手軽です。

JDKのアップデートで cacerts が刷新されると、期限切れ証明書は自動的に削除・差し替えされます。

古いJDKを長期間使い続けている環境では、まずこのコマンドで「いつ切れる証明書を抱えているか」を可視化することが、サイレント障害の予防につながります。

プログラム内からルート証明書を確認する方法

プログラム内からルート証明書を確認する方法を示すコード例の図解

Javaプログラムを実行して、ロードされている証明書を直接出力することも可能です。

コマンドでの確認はあくまで「ファイルの中身」の確認であり、実行時に正しく読み込まれているかを保証するものではないからです。

TrustManagerというクラスを使用するコードを書くことで、アプリケーションが実際に信頼している証明書リストをログに出力できます。

開発環境と本番環境で挙動が違う場合など、この方法でデバッグするのが最も確実です。

SSLContext と TrustManager で読み込まれる証明書

Javaのプログラム内でSSL通信を行う際、SSLContextというクラスが中心的な役割を果たします。

このSSLContextは初期化されるときに、デフォルトのTrustManagerを読み込みます。

このTrustManagerこそが、cacertsファイルから証明書をメモリ上に展開して持っている存在です。

プログラムコードからこのTrustManagerにアクセスすることで、現在メモリ上にある=実際に使われている証明書の一覧を取得できます。

これにより、起動オプション-Djavax.net.ssl.trustStoreなどで別のキーストアが指定されていないかも含めて確認できます。

Javaコード例:ロードされた証明書一覧を出力する

以下は、現在有効なTrustManagerからルート証明書のエイリアス(名前)一覧を表示する簡単なサンプルコードです。

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.security.KeyStore;
import java.security.cert.X509Certificate;

public class CertCheck {
    public static void main(String[] args) throws Exception {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init((KeyStore) null);

        for (TrustManager tm : tmf.getTrustManagers()) {
            if (tm instanceof X509TrustManager) {
                X509Certificate[] certs = ((X509TrustManager) tm).getAcceptedIssuers();
                System.out.println("読み込まれた証明書数: " + certs.length);
                for (X509Certificate cert : certs) {
                    System.out.println("Subject: " + cert.getSubjectX500Principal().getName());
                    System.out.println("Issuer: " + cert.getIssuerX500Principal().getName());
                    System.out.println("-------------------------");
                }
            }
        }
    }
}

このコードをコンパイルして実行すれば、パスの間違いや読み込みエラーの疑いを完全に晴らすことができます。

keytool/TrustManager/openssl の使い分け早見表

3つの確認手段はそれぞれ得意分野が違います。現場でムダなく使い分けるための早見表を、実体感ベースでまとめました。

確認手段確認できる対象期限切れ確認フィンガープリントroot権限体感スピード
keytool -listcacerts(ファイル)○(-v)編集時のみ必要1秒前後
TrustManagerコード実行時メモリ不要数秒(JVM起動込み)
openssl s_clientリモートサーバー側不要1秒前後

「ファイルを書き換えたのに反映されない」系のトラブルは TrustManager コード一択、「相手サーバーの証明書を疑う」場面は openssl s_client、それ以外の日常確認は keytool、と切り分けると最短で原因に到達できます。

「PKIX path building failed」など信頼されない証明書エラーの原因5パターンと対処法

信頼されない証明書エラーの原因パターンと対処法を示す図解

証明書エラーが出た場合、まずはキーストアへの証明書追加を検討します。

接続先のサーバーが社内システムや開発環境である場合、公的な認証局ではなく、独自の認証局(オレオレ認証局)を使っていることが多いからです。

エラーログに「unable to find valid certification path」と出ていれば、Javaがその証明書を知らない証拠なので、手動で信頼リストに入れてあげる必要があります。

ただし、無闇に追加するのではなく、本当に信頼してよい相手かを確認してから行うのが鉄則です。

証明書がcacertsに存在しない(unable to find valid certification path)

最も多い原因は、単純に対象のルート証明書がcacertsに入っていないことです。

公的なWebサイト(GoogleやYahooなど)であれば、Javaのインストール時に最初から有名な認証局の証明書が含まれているため、何もしなくてもつながります。

しかし、社内イントラネットのサーバーや、安価なSSL証明書を使っている場合、Javaのデフォルトリストに含まれていないことがあります。

この場合、ブラウザから対象のサイトにアクセスして証明書をファイルとしてエクスポートし、それをkeytoolでインポートするという手順が必要です。

「パスの構築に失敗しました」の仕組みと原因

エラーメッセージ「PKIX path building failed」は、証明書のチェーンが完成しなかったことを意味します。

証明書の検証はパズルのようなものです。

サーバーから渡されたピース(サーバー証明書)の親を探し、そのまた親を探し、最終的に自分の手元にある正解ピース(ルート証明書)と合致するかを確かめます。

この途中のピースが欠けていたり、最後のピースが合わなかったりすると、パス(経路)が構築できずにエラーとなります。

よくあるのが、サーバー側が中間証明書の設定を忘れているケースです。

この場合、Java側にルート証明書があっても、そこに至る道が切れているためエラーになります。解決策は2つです。

サーバー管理者に連絡して中間証明書を入れてもらうか、暫定的にクライアント(Java)側に中間証明書をインポートするかのいずれかです。

中間証明書の欠落(サーバー側の設定漏れ)

PKIXエラーの中で意外と多いのが、Java側ではなく サーバー側が中間証明書を配信し忘れているケースです。

この場合、ブラウザは中間証明書をキャッシュから補完してしまうため「ブラウザでは開けるのにJavaだけ落ちる」現象になります。

原因切り分けには、サーバー側のチェーン配信状況を確認するのが最短です。

openssl s_client -connect example.com:443 -showcerts < /dev/null | grep -E "s:|i:"

結果が「サーバー証明書 1枚しか返さない」なら、サーバー側で中間証明書が組み込まれていないことが確定します。

SSL Labs(https://www.ssllabs.com/ssltest/)でも「Chain issues: Incomplete」と表示されます。

恒久対処はサーバー管理者に中間証明書(fullchain.pem や CA bundle)を組み込んでもらうことですが、暫定対処として該当の中間証明書をクライアント側の cacertsimportcert しておくと通信は通るようになります。

Let's Encrypt の場合は https://letsencrypt.org/certificates/ から ISRG Root X1/X2 を入手できます。

自己署名証明書(オレオレ証明書)を信頼させる方法と注意点

開発環境などでよく使われる「自己署名証明書(オレオレ証明書)」は、デフォルトでは絶対に信頼されません。

これは誰の承認も受けずに自分で自分を証明している状態だからです。

自己署名証明書を使う場合は、Javaに対して「この証明書は例外的に信頼しろ」と教える必要があります。

具体的には、その自己署名証明書自体をルート証明書としてcacertsにインポートします。

こうすることで、Javaはその証明書を「信頼の起点」として扱うようになり、エラーが解消されます。

証明書を追加する際の危険性とベストプラクティス

証明書をcacertsに追加する際は、セキュリティリスクを理解しておく必要があります。

一度信頼リストに追加してしまうと、その証明書を使って署名されたあらゆる通信を無条件に信じてしまうことになるからです。

もし悪意のある第三者が作成した証明書を追加してしまうと、通信の盗聴や改ざんを行われても気づけなくなります。

ベストプラクティスとしては、以下の点を守りましょう。

  1. 入手元を確認する:メールで送られてきた不明なファイルなどは絶対に追加しない。
  2. フィンガープリントを照合する:インポート時に表示されるハッシュ値が、正当なものと一致するか確認する。
  3. 専用のキーストアを使う:可能な限り、システム全体のcacertsを汚すのではなく、アプリケーション専用のキーストアファイルを用意して読み込ませる。

JKSとPKCS12の違い|Java9以降のキーストア形式変更

Javaのキーストアには JKS(Java KeyStore)と PKCS12 の2種類があります。

Java9以降は新規キーストア作成時のデフォルトがPKCS12に変更されました。

  • JKS: Java独自形式。古いシステムとの互換性のためだけに残されている
  • PKCS12: 業界標準(RFC 7292)。OpenSSLや他言語ともそのまま相互利用できる

Java8時代に作ったJKSをJava11以降のkeytoolで開くと、こんな警告が出ることがあります。

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype pkcs12".

動作上は無視しても問題ありませんが、新規でキーストアを作るならPKCS12を選ぶのが原則です。

既存JKSのPKCS12への変換は、警告メッセージにある keytool -importkeystore 一発で完了します。

現役エンジニアが見るハマりどころTOP3

証明書エラーで「公式手順は試したのに直らない」と詰まる現場は、だいたい次の3パターンです。最初にこのコマンドを打つだけで切り分けが進みます。

  1. TOP1:複数JDK環境で、IDEとターミナルが別のjavaを使っている
    確認: which java と IDEの「Project Structure → SDK」のパスが一致しているか
  2. TOP2:-Djavax.net.ssl.trustStore を指定しているのに、システムのcacertsを編集している
    確認: 起動コマンド/Spring Bootのapplication.ymlJAVA_OPTSで trustStore指定があるか grep
  3. TOP3:Mavenの依存JARに古いCA証明書が同梱され、クラスパスで上書きされている
    確認: mvn dependency:tree | grep -i bouncy 等でCA関連ライブラリの混入を疑う

逆に言えば、これらに該当しなければ素直にJDKバージョンアップで解決するケースが大半です。

手当たり次第に importcert する前に、上記3点だけ確認するクセをつけると無駄なkeytool操作が激減します。

Javaのルート証明書を更新する手順|JDKバージョンアップとkeytool手動追加の使い分け

Javaのルート証明書を更新する手順を示す図解

ルート証明書の更新は、基本的にはJDKのバージョンアップで行うのが推奨です。

OracleやOpenJDKのコミュニティが、信頼できる認証局のリストを精査し、定期的なアップデートで最新の状態に保ってくれているからです。

古いJDK(例えばJava8の初期パッチなど)を使い続けていると、Let's Encryptの新しいルート証明書(RSA系のメインチェーンであるISRG Root X1や、ECDSA用のISRG Root X2)に対応できず、突然つながらなくなることがあります。

原因はLet's Encryptが2024年6月6日にDST Root CA X3とのクロス署名付き証明書の新規発行を停止し、同年9月30日にそのクロス署名自体が完全に失効したことです。

それ以降、古いJDKでは自己署名のISRG Root X1を直接信頼している必要があります。

手動での追加はあくまで例外的な対応と考え、基本はJDK全体の更新で対応するのが最も安全で楽な運用です。

JDKアップデート(Java17/Java21/Java25)で自動的に証明書が更新される仕組み

Javaのアップデートパッケージには、その時点での最新のcacertsファイルが含まれています。

JDKをアップデートすると、古いcacertsは新しいものに置き換えられるか、新しいフォルダにインストールされたJDKが新しいcacertsを使うようになります。

この置き換えによって、世の中で無効化された古い認証局は削除され、新しく認定された認証局が追加される仕組みです。

セキュリティの観点からも、Java自体の脆弱性修正と合わせて証明書も最新になるため、定期的なJavaのアップデート運用を計画することが重要です。

作業前に必ずcacertsをバックアップする方法

keytoolで証明書を追加・削除する前に、必ず cacerts をバックアップしてください。

誤って必要な証明書を削除してしまうと、JDKを再インストールするまで復旧できなくなります。

# macOS / Linux(タイムスタンプ付きでバックアップ)
sudo cp "$JAVA_HOME/lib/security/cacerts" "$JAVA_HOME/lib/security/cacerts.bak.$(date +%Y%m%d_%H%M%S)"

# Windows(PowerShell)
Copy-Item "$env:JAVA_HOME\lib\security\cacerts" "$env:JAVA_HOME\lib\security\cacerts.bak.$(Get-Date -Format yyyyMMdd_HHmmss)"

本番サーバーで作業する場合は、上記に加えて社外ストレージ(社内Wiki等)にもコピーを残しておくと安心です。

トラブル発生時は、バックアップを元のファイル名に戻すだけで即座にロールバックできます。

手動で証明書を追加/削除する方法(keytool add/delete)

どうしても手動で更新が必要な場合は、importcert(追加)とdelete(削除)コマンドを使います。

追加する場合:

keytool -importcert -alias "任意の名前" -file "証明書ファイル.cer" -keystore "cacertsのパス" -storepass changeit

実行すると、証明書のOwner・Issuer・有効期限・フィンガープリントが表示されたあとに、以下のようなプロンプトが出ます。

この証明書を信頼しますか? [いいえ]:  y
証明書がキーストアに追加されました
[cacertsを格納するファイルに変更を書き込んでいます]

デフォルトの答えは「いいえ」([いいえ])なので、何も入力せずEnterを押すと証明書は追加されません。

必ずyまたはyesと明示的に入力する必要があります。

ここで表示されるフィンガープリントは、事前にopenssl s_clientやブラウザで確認した値と目視で照合してから承認するのが安全です。

削除する場合:

keytool -delete -alias "削除したい名前" -keystore "cacertsのパス" -storepass changeit

削除する際は、エイリアス(名前)が正確である必要があります。事前に-listコマンドで正確なエイリアスを確認してから実行しましょう。

また、操作前には必ずcacertsファイルのバックアップコピーを取っておくことを強く勧めます。

なお、システムのcacertsを編集するにはLinux/macOSではroot権限、Windowsでは管理者権限が必要です。

cacerts直編集 vs アプリ別trustStore:現場での判断軸

「証明書を追加する際、システムのcacertsを直接いじるべきか、アプリ専用のtrustStoreを別途用意すべきか」は現場で必ず迷うポイントです。

私は次の基準で使い分けています。

  • 個人開発・社内検証環境: cacerts直編集でOK。手数が少なく即解決できる
  • 商用本番・チーム共有のサーバー: アプリ別trustStore一択。JDKを再インストールしても証明書設定が消えず、Infrastructure as Code とも相性が良い
  • Docker/Kubernetes 環境: cacertsを毎回書き換える運用は再現性が壊れやすいため、imageビルド時にtrustStoreを焼き込み、起動オプションで読み込むのが推奨

「とりあえず動かすならcacerts、運用するならtrustStore」と覚えておくと迷いません。

商用環境では「JDK更新で証明書設定が吹き飛んだ」事故が現実に起きるため、最初からアプリ別trustStoreで始める方が安全です。

あわせて読む

よくある疑問Q&A

Javaのルート証明書に関するよくある疑問Q&Aを示す図解

証明書ストアは複数存在するのか?

はい、複数存在する可能性があります。

Javaシステム全体のデフォルトであるlib/security/cacertsのほかに、代替キーストア(jssecacerts)が存在する場合があるからです。

jssecacertsはJavaインストール直下のlib/security/に作成されるファイルで、存在する場合はcacertsよりも優先されます。

意図せずjssecacertsが作られていて、そちらの古い情報を参照しているためにエラーが直らない、というケースも稀にあります。

アプリケーションごとに異なるキーストアを使える?

はい、使えます。

Javaアプリケーションを起動する際のオプションで指定可能です。

-Djavax.net.ssl.trustStore=/path/to/mykeystore

-Djavax.net.ssl.trustStorePassword=mypassword

この方法を使えば、システム全体のcacertsを書き換えることなく、そのアプリ専用の証明書設定を持たせることができます。

権限の問題でシステムファイルを触れない場合などに有効です。

Spring Boot/Tomcatで独自キーストアを指定する方法

フレームワーク利用時にシステム全体の cacerts ではなくアプリ専用キーストアを使うパターンは、用途別に設定箇所が異なる点に注意してください。

外向き(HTTPSクライアント)と内向き(mTLSサーバー)でキーが別物です。

外向きHTTPSクライアント(RestTemplate/WebClient等):JVM起動オプションで指定

# Spring Boot / Tomcat 共通:JVM システムプロパティで指定
export JAVA_OPTS="-Djavax.net.ssl.trustStore=/opt/app/my-truststore.p12 -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=PKCS12"

内向きmTLS(クライアント証明書認証を要求するサーバー側):Spring Bootのserver.ssl.*

# application.properties — 組み込みTomcatがクライアント証明書を検証する用途
server.ssl.client-auth=need
server.ssl.trust-store=classpath:my-truststore.p12
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=PKCS12

「外部APIをHTTPSで叩いたらPKIXエラー」のときに server.ssl.trust-store をいじっても効きません。

これは組み込みサーバーがクライアント証明書を検証するときのトラストストアであり、アウトバウンド通信には適用されないためです。

外向きの解決策はJVMシステムプロパティ(-Djavax.net.ssl.trustStore)か、各HTTPクライアントにSSLContextを注入する方法になります。

この方式ならシステムの cacerts を汚さず、デプロイのたびに自動で正しいキーストアが読み込まれます。

本番運用では root権限を要求する cacerts 直編集よりも、こちらが推奨です。

あわせて読む
あわせて読む
あわせて読む

Java 8 / Java 11 / Java 17 / Java 21 / Java 25 で証明書管理は何が違う?

基本的なコマンド操作や仕組みは変わりませんが、ファイルの配置場所と初期含まれている証明書の種類が異なります。2025年9月にリリースされたJava25が現行のLTS版で、Java21からの移行を検討している現場も増えています。

Java11/Java17/Java21/Java25といった新しいLTSバージョンでは、ディレクトリ構成が整理されています。

また、MD5は古くから無効化されており、SHA-1署名済みTLSサーバー証明書チェーンのデフォルト拒否は、2023年4月リリースの 8u361/11.0.18/17.0.6 以降jdk.certpath.disabledAlgorithms に追加されました。

TLS 1.0/1.1 のデフォルト無効化は Java 8u291/11.0.11(2021年4月)以降です。

これはJava 21固有の挙動ではなく、Java25を含むこれより新しい環境すべてに共通する仕様で、古いサーバーへの接続失敗の典型的な原因になります。

Java8で動いていた証明書がJava17でエラーになる場合は、配置場所だけでなく、証明書の暗号強度が現在のセキュリティ基準を満たしているかも確認が必要です。

バージョンごとの確認・切り替えコマンドは以下の記事にまとめています。

あわせて読む

よくある質問

Q1. cacertsとは何ですか?

A1. cacertsとは、Javaが標準で信頼するルート証明書を格納しているキーストアファイルのことです。JavaのSSL/TLS通信で「この証明書を信頼していいか」を判断する際の基準になります。

Q2. cacertsの読み方は?

A2. 「シーエーサーツ」または「カサーツ」と読みます。Certificate Authority certificatesの略で、公式な読み方が定められているわけではありませんが、現場では英語表記のまま「シーエーサーツ」と呼ばれることが多いです。

Q3. cacertsのデフォルトパスワードは何ですか?

A3. 「changeit」です。Java25時点でも変更されておらず、UbuntuやRHELのca-certificates-javaパッケージでも踏襲されています。セキュリティ上のリスクとして知られていますが、慣習的にそのまま使われることがほとんどです。

Q4. cacertsファイルはどこにありますか?

A4. Java11以降では$JAVA_HOME/lib/security/cacerts(Windowsは%JAVA_HOME%\lib\security\cacerts)にあります。Java8以前はjre/lib/security/cacertsのようにjreフォルダの中に配置されている点が異なります。

Q5. 「PKIX path building failed」はどうすれば解決しますか?

A5. 証明書チェーンが途切れていることが原因です。サーバー側の中間証明書配信漏れか、Java側にルート証明書が未登録かのいずれかを疑い、openssl s_clientでチェーンを確認したうえで、必要な証明書をkeytool -importcertでcacertsに追加します。

Q6. jssecacertsとcacertsの違いは何ですか?

A6. どちらもJavaのキーストアファイルですが、jssecacertsが存在する場合はcacertsより優先して読み込まれます。意図せず作成された古いjssecacertsが原因でエラーが直らないケースもあるため、両方の存在を確認することが重要です。

まとめ:Javaのルート証明書確認は「場所」と「keytool」を理解すれば簡単

Javaのルート証明書にまつわるトラブルは難解に見えますが、押さえるべきポイントは実はシンプルです。

ここまで解説してきた通り、問題の9割は「見ているファイルが違う」か「証明書が入っていない」のどちらかだからです。

  • 場所の特定: java.home プロパティで実際に使われているパスを確認する。
  • 中身の確認: keytool -list で対象の証明書があるかを見る。
  • 追加の対応: 足りなければ keytool -importcert で追加する。

この3ステップを冷静に実行すれば、どんな証明書エラーも怖くありません。

次にあなたが「PKIX path building failed」に出会ったときは、ぜひこの記事のコマンドをコピーして、ターミナルに貼り付けてみてください。

きっと驚くほどスムーズに解決できるはずです。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Java入門