■ サンプル
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* キーストア管理クラス.
*/
public class KeyStoreManager {
public static void main(String[] args) {
String keyStorePath = Paths.get("etc", "demo.keystore").toString();
String keyStorePassword = "changeit";
try {
KeyStoreManager keyStoreManager = new KeyStoreManager(keyStorePath, keyStorePassword);
X509Certificate x509Certificate = keyStoreManager.getCertificatesByAlias("demo_alias");
System.out.println("Type : " + x509Certificate.getType());
System.out.println("Before : " + x509Certificate.getNotBefore());
System.out.println("After : " + x509Certificate.getNotAfter());
System.out.println("Issuer Name : " + x509Certificate.getIssuerX500Principal().getName());
System.out.println("Subject Name : " + x509Certificate. getSubjectX500Principal().getName());
System.out.println();
// 追加
String certificatePath = Paths.get("etc", "cacert.crt").toString();
keyStoreManager.addCertificate("demo_alias2", certificatePath);
List<X509Certificate> x509Certificates = keyStoreManager.getCertificatesByPrefixAlias("demo_alias");
int counter = 1;
for (X509Certificate certificate : x509Certificates) {
System.out.println(counter);
System.out.println("Type : " + certificate.getType());
System.out.println("Before : " + certificate.getNotBefore());
System.out.println("After : " + certificate.getNotAfter());
System.out.println("Issuer Name : " + certificate.getIssuerX500Principal().getName());
System.out.println("Subject Name : " + certificate. getSubjectX500Principal().getName());
counter++;
}
System.out.println();
// エクスポート機能
String certificateExportPath = Paths.get("etc", "export.crt").toString();
keyStoreManager.exportCertificate("demo_alias2", certificateExportPath);
KeyStoreManager keyStoreManagerForExport = new KeyStoreManager(keyStorePath, keyStorePassword);
X509Certificate x509CertificateForExport = keyStoreManagerForExport.getCertificatesByAlias("demo_alias2");
System.out.println("Type For Export : " + x509CertificateForExport.getType());
System.out.println("Before For Export : " + x509CertificateForExport.getNotBefore());
System.out.println("After For Export : " + x509CertificateForExport.getNotAfter());
System.out.println("Issuer Name For Export : " + x509CertificateForExport.getIssuerX500Principal().getName());
System.out.println("Subject Name For Export : " + x509CertificateForExport. getSubjectX500Principal().getName());
System.out.println();
// 削除
keyStoreManager.deleteCertificate("demo_alias2");
x509Certificates = keyStoreManager.getCertificatesByPrefixAlias("demo_alias");
counter = 1;
for (X509Certificate certificate : x509Certificates) {
System.out.println(counter);
System.out.println("Type : " + certificate.getType());
System.out.println("Before : " + certificate.getNotBefore());
System.out.println("After : " + certificate.getNotAfter());
System.out.println("Issuer Name : " + certificate.getIssuerX500Principal().getName());
System.out.println("Subject Name : " + certificate.getSubjectX500Principal().getName());
counter++;
}
} catch (Exception ex) {
ex.getStackTrace();
}
}
private static final String CERTIFICATE_TYPE = "X.509";
/** キーストア・パスワード. */
private char[] keyStorePasswordBytes;
/** キーストア・ファイル. */
private File keyStoreFile;
/** キーストア. */
private KeyStore keyStore;
// コンストラクタ
public KeyStoreManager(String keyStorePassword)
throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
this(KeyStoreManager.getDefaultKeyStorePath(), keyStorePassword);
}
public KeyStoreManager(String keyStorePath, String keyStorePassword)
throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
this.keyStoreFile = new File(keyStorePath);
this.keyStorePasswordBytes = keyStorePassword.toCharArray();
this.keyStore = KeyStoreManager.geyKeyStore(this.keyStoreFile, this.keyStorePasswordBytes);
}
// Public Static メソッド
// デフォルトのキーストアパスを取得
public static String getDefaultKeyStorePath() {
return Paths.get(System.getProperty("java.home"), "lib", "security", "cacerts").toString();
}
// 期限切れの判定
public static boolean isExpiredCertificate(X509Certificate x509Certificate) {
try {
x509Certificate.checkValidity();
} catch (CertificateExpiredException ex) {
return true;
} catch (CertificateNotYetValidException ex) {
// Go Through
}
return false;
}
// Public メソッド
// エイリアス一覧取得
public Enumeration<String> getKeyStoreAliases() throws KeyStoreException {
return this.keyStore.aliases();
}
// 証明書の取得
public X509Certificate getCertificatesByAlias(String alias) throws KeyStoreException {
Certificate certificate = this.keyStore.getCertificate(alias);
if (certificate != null && certificate.getType().equals(CERTIFICATE_TYPE)) {
return (X509Certificate) certificate;
} else {
return null;
}
}
// 証明書一覧の取得
public List<X509Certificate> getCertificatesByPrefixAlias(String prefixAlias) throws KeyStoreException {
List<X509Certificate> returnValues = new ArrayList<>();
String targetPrefixAlias = prefixAlias.toLowerCase();
Enumeration<String> aliases = this.getKeyStoreAliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (alias == null || !alias.startsWith(targetPrefixAlias)) {
continue;
}
X509Certificate x509Certificate = this.getCertificatesByAlias(alias);
if (x509Certificate != null) {
returnValues.add(x509Certificate);
}
}
return returnValues;
}
// 追加
public void addCertificate(String alias, String certificateFilePath)
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate x509Certificate = KeyStoreManager.getX509Certificate(certificateFilePath);
this.keyStore.setCertificateEntry(alias, x509Certificate);
this.save();
}
// 追加
public void addCertificate(String alias, byte[] keyStoreBytes)
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate x509Certificate = KeyStoreManager.getX509Certificate(keyStoreBytes);
this.keyStore.setCertificateEntry(alias, x509Certificate);
this.save();
}
// 削除
public void deleteCertificate(String alias)
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
this.keyStore.deleteEntry(alias);
this.save();
}
// エクスポート機能
public void exportCertificate(String alias, String exportFilePath)
throws CertificateEncodingException, IOException, KeyStoreException {
try (FileOutputStream outputStream = new FileOutputStream(new File(exportFilePath))) {
X509Certificate x509Certificate = this.getCertificatesByAlias(alias);
outputStream.write(x509Certificate.getEncoded());
}
}
// Private Static メソッド
// キーストアの取得
private static KeyStore geyKeyStore(File keyStoreFile, char[] keyStorePasswordBytes)
throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream fileInputStream = new FileInputStream(keyStoreFile)) {
keyStore.load(fileInputStream, keyStorePasswordBytes);
return keyStore;
}
}
// 証明書ファイル→X509Certificate を変換
private static X509Certificate getX509Certificate(String certificateFilePath)
throws IOException, CertificateException {
try (InputStream inputStream = new FileInputStream(new File(certificateFilePath))) {
CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_TYPE);
return (X509Certificate) certificateFactory.generateCertificate(inputStream);
}
}
// 証明書(byte[])→X509Certificate を変換
private static X509Certificate getX509Certificate(byte[] certificates)
throws IOException, CertificateException {
try (InputStream inputStream = new ByteArrayInputStream(certificates)) {
CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_TYPE);
return (X509Certificate) certificateFactory.generateCertificate(inputStream);
}
}
// Private メソッド
// 保存
private void save() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
try (FileOutputStream fileOutputStream = new FileOutputStream(this.keyStoreFile)) {
this.keyStore.store(fileOutputStream, this.keyStorePasswordBytes);
}
}
}
出力結果例
Type : X.509
Before : Fri Sep 08 22:58:04 JST 2017
After : Mon Sep 06 22:58:04 JST 2027
Issuer Name : CN=localhost,OU= ...
Subject Name : CN=localhost,OU= ...
1
Type : X.509
Before : Sun Jun 25 17:21:07 JST 2017
After : Wed Jun 24 17:21:07 JST 2020
Issuer Name : 1.2.840.113549.1.9.1=#16186469...
Subject Name : 1.2.840.113549.1.9.1=#16186469...
2
Type : X.509
Before : Fri Sep 08 22:58:04 JST 2017
After : Mon Sep 06 22:58:04 JST 2027
Issuer Name : CN=localhost,OU= ...
Subject Name : CN=localhost,OU= ...
Type For Export : X.509
Before For Export : Sun Jun 25 17:21:07 JST 2017
After For Export : Wed Jun 24 17:21:07 JST 2020
Issuer Name For Export : 1.2.840.113549.1.9.1=#161864...
Subject Name For Export : 1.2.840.113549.1.9.1=#161864...
1
Type : X.509
Before : Fri Sep 08 22:58:04 JST 2017
After : Mon Sep 06 22:58:04 JST 2027
Issuer Name : CN=localhost,OU= ...
Subject Name : CN=localhost,OU= ...
補足:CNやOUなどの値を個別に扱いたい場合
* 以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37112129.html