JavaのAPIを使用して証明書にアクセスする(keytoolは使用せずに)

証明書の期限切れが世の中をにぎわせている今、プログラムから証明書の期限を取得してAPIとして期限切れかどうかをチェックできるものがあるといいよなぁと思い、Javaから証明書にアクセスする方法を調べてみました。

証明書の自動更新とかの実装例を見てると3か月に1回の定期起動みたいな感じになっているので、証明書の中身を見て、切れそうになったら更新みたいな感じで実装できると幸せになる?ならない?もうありそう?

とりあえず、簡単にできます。

keystoreから取得する場合

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Enumeration;

public class KeyStoreAccess {

    public static void main(String[] args) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {

        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");

        // Javaのキーストアから取得
        KeyStore ks = KeyStore.getInstance("JKS");
        try (FileInputStream in = new FileInputStream("C:\\Program Files\\Java\\jdk-11\\lib\\security\\cacerts")) {
            ks.load(in, "changeit".toCharArray()); //changeitはJavaのキーストアのデフォルトパスワード
        }
        Enumeration<String> aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            String alias = aliases.nextElement();
            X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);
            System.out.println("名前:" + alias + ".発行者:" + certificate.getIssuerX500Principal().getName() + "," + f.format(certificate.getNotAfter()) + "まで");
        }
    }
}

単体の証明書から取得する場合

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Enumeration;

public class KeyStoreAccess {

    public static void main(String[] args) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {

        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");

        // 直接証明書を取得する。
        try (FileInputStream fis = new FileInputStream("C:\\work\\aaa.cer")) {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);

            System.out.println("発行者:" + cert.getIssuerX500Principal().getName() + "," + f.format(cert.getNotAfter()) + "まで");
        }
    }
}

参考:

Java PKI APIプログラマーズ・ガイド

http://apis.jpn.ph/fswiki/wiki.cgi?page=Java%2Fkeytool