Java 提供完整的 java.security、java.security.cert API 支援 X.509 憑證全生命週期操作。本文彙整九大實戰場景,代碼即拿即用。
import java.security.*;
import java.security.cert.*;
import java.io.*;
import sun.security.x509.*; // 內部 API,僅示範簽發流程
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream("out.csr");
Certificate cert = cf.generateCertificate(in);
System.out.println(cert.toString());
String pwd = "123456";
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(".keystore"), pwd.toCharArray());
Certificate cert = ks.getCertificate("alias"); // 指定別名
X509Certificate x509 = (X509Certificate) cert;
System.out.println("版本: " + x509.getVersion());
System.out.println("序列號: " + x509.getSerialNumber().toString(16));
System.out.println("主體: " + x509.getSubjectDN());
System.out.println("簽發者: " + x509.getIssuerDN());
System.out.println("有效期: " + x509.getNotBefore() + " ~ " + x509.getNotAfter());
System.out.println("簽名演算法: " + x509.getSigAlgName());
// 公鑰原始位元組
byte[] pkBytes = x509.getPublicKey().getEncoded();
Enumeration aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
Certificate c = ks.getCertificate(alias);
// 處理每個條目
}
ks.load(new FileInputStream(".keystore"), "123456".toCharArray());
ks.store(new FileOutputStream(".keystore"), "654321".toCharArray());
Certificate[] chain = ks.getCertificateChain("alias");
PrivateKey pk = (PrivateKey) ks.getKey("alias", "oldKeyPwd".toCharArray());
// 覆蓋或新增:相同 alias 覆蓋,不同則新增
ks.setKeyEntry("alias", pk, "newKeyPwd".toCharArray(), chain);
ks.store(new FileOutputStream("another.keystore"), "storePwd".toCharArray());
if (ks.containsAlias("sage")) {
ks.deleteEntry("sage");
ks.store(new FileOutputStream(".keystore"), "storePwd".toCharArray());
}
ks.getCertificate("caroot")、ks.getKey("ca", "caKeyPwd".toCharArray())X509CertInfo 取得 X500NameCertificateFactory.generateCertificate("user.csr")CertificateValidity(begin, end)CertificateSerialNumber(如時間戳)X509CertInfo.ISSUERAlgorithmId.md5WithRSAEncryption_oidX509CertImpl newCert = new X509CertImpl(certInfo);
newCert.sign(caPrivateKey, "MD5WithRSA");
ks.setCertificateEntry("user_signed", newCert)X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream("aa.crt"));
try {
cert.checkValidity(new Date()); // 當前時間
System.out.println("OK");
} catch (CertificateExpiredException e) { System.out.println("Expired"); }
catch (CertificateNotYetValidException e) { System.out.println("Not yet valid"); }
Certificate caCert = cf.generateCertificate(new FileInputStream("caroot.crt"));
PublicKey caPubKey = caCert.getPublicKey();
try {
cert.verify(caPubKey); // 拋出異常即驗證失敗
System.out.println("Signature valid");
} catch (Exception e) { System.out.println("Invalid: " + e); }
sun.security.x509.* 為內部 API,生產環境建議改用 BouncyCastle 等標準庫try-with-resources 關閉流,防止檔案鎖定