iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
Software Development

我是Java工程師,關於密碼學我想懂的不多系列 第 10 篇

Day09 - Java 的密碼學地圖:JCA / JCE / Provider

  • 分享至 

  • xImage
  •  

前言

Java 的密碼學地圖可以分為JCA、JCE、JSEE、JAAS,與密碼學相關的主要內容會在JCA與JCE,JSEE則是網路傳輸安全我們留到之後再說,簡介如下

  • JCA (Java Cryptography Architecture):密碼學基礎骨幹與憑證管理
  • JCE (Java Cryptography Extension):資料加解密與 HMAC 簽章
  • JSSE(Java Secure Socket Extension):TLS/SSL 網路傳輸安全
  • JAAS(Java Authentication & Authorization Service):身分驗證與權限授權

一、JCA 與 JCE 架構

https://ithelp.ithome.com.tw/upload/images/20260924/20128084bwYjECdiMv.png
在 Java 密碼學架構(JCA)中,為了實現「演算法獨立性」與「可插拔架構」,核心設計圍繞著兩個關鍵角色:Engine Class(引擎類別)與 Provider(提供者)。它們以 API 與 SPI 分離的形式相互協作

1. JCA (Java Cryptography Architecture) —— 密碼學核心骨幹

  • 核心職責:處理雜湊(Hash)、數位簽章、金鑰對生成、安全亂數與憑證儲存。
  • 主要 Package:java.security.*
  • 代表性類別:
  • MessageDigest:計算雜湊值(如 SHA-256、MD5)。
  • Signature:進行非對稱數位簽章與驗章。
  • KeyPairGenerator:生成 RSA / ECC 公私鑰對。
  • KeyStore:管理與讀取 .jks 或 .p12 金鑰憑證庫。
  • SecureRandom:產生密碼學安全等級的偽亂數。

2. JCE (Java Cryptography Extension) —— 高級資料加解密擴充

JCE 是 JCA 的功能延伸。早期因為美國對高強度加密演算法出口限制,JCE 曾作為獨立擴充套件發布,如今已完全內建於 JDK 中(但也因此保留了 javax.crypto 這個獨立 Package)。

  • 核心職責:專注於「對稱與非對稱資料加解密」、「金鑰生成」、「訊息鑑別碼 (MAC)」與「金鑰交換」。
  • 主要 Package:javax.crypto.*
  • 代表性類別:
  • Cipher:加解密的核心核心類別(如 AES、DES、RSA 加解密)。
  • KeyGenerator / SecretKey:生成對稱式金鑰(如 AES Key)。
  • Mac:計算訊息鑑別碼(如 API 對接常要求的 HMAC-SHA256 簽章)。
  • KeyAgreement:Diffie-Hellman (DH) 金鑰協商。

二、Provider

JCA 採用了「服務提供者架構(Provider Architecture)」,API 層(如 Cipher、MessageDigest)只負責定義統一介面,真正的加密演算法與運算邏輯,全靠底層掛載的 Provider 來實作。

在 Java 生態系中,常見的 JCA Provider 可以分為以下四大類:

1. JDK 內建預設 Provider

Oracle JDK 與 OpenJDK 預設內建了多個 Provider,負責處理絕大多數基礎密碼學需求:

  • Sun:Java 最古老的基礎 Provider,提供基本雜湊(SHA-1、SHA-256)、DSA 簽章與 KeyStore 基礎實作。
  • SunJCE:對稱加密與資安擴充核心,負責 AES、DES、ChaCha20、HMAC、Diffie-Hellman 金鑰交換等實作。
  • SunJSSE:專門負責 TLS/SSL 通訊協定的握手與加密通道建立。
  • SunRSASign:專門處理 RSA 金鑰生成、RSA 加解密與 RSA 數位簽章。

2. 開發者必知:第三方 Provider

當 JDK 預設 Provider 支援的演算法不夠用(例如舊版 Java 不支援某些新式橢圓曲線或演算法),或是需要資安合規認證時,第三方 Provider 是最佳選擇:

  • Bouncy Castle (BC):
  • 地位:Java 領域最知名、最主流的第三方密碼學 Provider。
  • 特點:支援的演算法種類遠超 JDK 內建(如 Ed25519、Post-Quantum 後量子加密、AES-CCM 等),且支援舊版 Java 無法實現的新密碼標準。
  • Bouncy Castle FIPS (BCFIPS):
  • 地位:專為資安合規(Compliance)打造的獨立分支。
  • 特點:通過 FIPS 140-2 / FIPS 140-3 官方認證,金融業、政府專案或高資安要求的系統都會指定導入此 Provider。

3. 高效能 / Native 加速 Provider(C/C++ 原生庫)

Java 純程式碼處理高併發的 AES-GCM 或 TLS 加解密時,CPU 消耗較大。因此許多大廠推出了透過 JNI 呼叫 C/C++ 原生密碼庫(如 OpenSSL / BoringSSL)的 Provider 來榨乾硬體效能:

  • Conscrypt (Google):
  • 技術底層:打包了 Google 的 BoringSSL(OpenSSL 的分支)。
  • 應用場景:Android 系統預設使用;伺服器端(如 gRPC、Netty)常用來替換 Java 預設 JSSE,以獲得極高的 TLS 吞吐量與低延遲。
  • Amazon Corretto Crypto Provider (ACCP):
  • 技術底層:AWS 開發,透過 JNI 連結 C 語言優化的 OpenSSL / libcrypto。
  • 特點:專門針對 AES-GCM 與 64 位元 Linux 環境最佳化,CPU 加密吞吐量可提升數倍,AWS 環境與高併發服務常用。

4. 硬體與企業特定 Provider

  • SunPKCS11:
  • 用途:硬體安全模組(HSM)與晶片卡(Smart Card)的橋樑。
  • 運算方式:它不親自做加密運算,而是透過 PKCS#11 標準介面,將金鑰產生與加解密指令轉發給實體的 HSM 硬體 處理,私鑰永遠不離開硬體。
  • **IBMJCE / IBMJCECCA**:
  • 用途:IBM Java SDK / WebSphere 伺服器專用,支援 IBM 大型機(Mainframe)與硬體密碼卡加速。

Java 開發實務:如何檢視與動態註冊 Provider?

1. 查閱當前 JVM 已載入的 Provider 優先順序:

import java.security.Provider;
import java.security.Security;

public class ProviderList {
    public static void main(String[] args) {
        int index = 1;
        for (Provider provider : Security.getProviders()) {
            System.out.println(index++ + ". " + provider.getName() + " (v" + provider.getVersionStr() + ")");
        }
        //        列印結果
        //        1. SUN (v21)
        //        2. SunRsaSign (v21)
        //        3. SunEC (v21)
        //        4. SunJSSE (v21)
        //        5. SunJCE (v21)
        //        6. SunJGSS (v21)
        //        7. SunSASL (v21)
        //        8. XMLDSig (v21)
        //        9. SunPCSC (v21)
        //        10. JdkLDAP (v21)
        //        11. JdkSASL (v21)
        //        12. SunMSCAPI (v21)
        //        13. SunPKCS11 (v21)
    }
}

2. 動態註冊第三方 Provider(以 Bouncy Castle 為例):

<!-- Source: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk18on</artifactId>
    <version>1.86</version>
    <scope>compile</scope>
</dependency>

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import javax.crypto.Cipher;

// 方法 A:全域註冊(掛載到 JVM 系統中)
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); // 指定使用 BC Provider

// 方法 B:單次呼叫時直接傳入 Provider 物件
Cipher cipherB = Cipher.getInstance("AES/GCM/NoPadding", new BouncyCastleProvider());

Reference

  • Security Developer’s Guide - Oracle

上一篇
Day08 - 現代密碼學基礎 -- 單向雜湊函數
系列文
我是Java工程師,關於密碼學我想懂的不多 共 10 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言