首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 數位憑證操作全攻略:從讀取、驗證到簽發與金鑰庫管理

     編輯:Java 相關知識

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());
}

八、CA 簽發使用者憑證完整流程

  1. 載入 CA 憑證與私鑰:ks.getCertificate("caroot")、ks.getKey("ca", "caKeyPwd".toCharArray())
  2. 提取 CA 主體資訊作為簽發者:解析 X509CertInfo 取得 X500Name
  3. 載入待簽發 CSR:CertificateFactory.generateCertificate("user.csr")
  4. 設定新憑證屬性:
    • 有效期:CertificateValidity(begin, end)
    • 序列號:CertificateSerialNumber(如時間戳)
    • 簽發者:X509CertInfo.ISSUER
    • 簽名演算法:AlgorithmId.md5WithRSAEncryption_oid
  5. 生成並簽名:
    X509CertImpl newCert = new X509CertImpl(certInfo);
    newCert.sign(caPrivateKey, "MD5WithRSA");
    
  6. 寫入金鑰庫:ks.setCertificateEntry("user_signed", newCert)

九、憑證驗證雙重保障

1. 有效期驗證

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"); }

2. 簽名鏈驗證

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 關閉流,防止檔案鎖定
  • 簽發憑證時序列號需唯一,生產環境建議使用安全隨機數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved