來自Java官方的文檔,作備忘使用。
簡介:
Java平台非常強調安全性,包括語言安全,密碼學,公鑰基礎設施,認證,安全通信和訪問控制。
JCA是平台的一個主要部分,包含一個“提供者”體系結構和一組用於數字簽名,消息摘要(哈希),證書和證書驗證,加密(對稱/非對稱塊/流密碼),密鑰生成管理和安全隨機數生成等等。這些API允許開發人員將安全性輕松集成到應用程序代碼中。這個架構是圍繞以下原則設計的:
實現獨立性:應用程序不需要實現安全算法。相反,他們可以從Java平台請求安全服務。安全服務在提供者(見下文)中實現,通過標准接口插入Java平台。應用程序可能依靠多個獨立的提供者來提供安全功能。
實現互操作性:提供者可以跨應用程序進行互操作。具體而言,應用程序不綁定到特定的提供者,而提供者也不綁定到特定的應用程序。
算法可擴展性:Java平台包括許多內置的提供者,這些提供者實現了當今廣泛使用的一組基本的安全服務。但是,一些應用程序可能依賴尚未實施的新興標准或專有服務。 Java平台支持安裝實現這些服務的定制提供程序。
JDK中提供的其他密碼通信庫使用JCA提供程序體系結構,但在別處進行了介紹。 Java Secure Socket Extension (JSSE) Java安全套接字擴展(JSSE)提供對 Secure Socket Layer(SSL)和 Transport Layer Security(TLS)實現的訪問。 Java通用安全服務(JGSS)(通過Kerberos)API以及簡單身份驗證和安全層(SASL)也可用於在通信應用程序之間安全地交換消息。
術語注釋:
在JDK 1.4之前,JCE是一個非捆綁產品,因此,JCA和JCE被定期稱為獨立的,獨特的組件。由於JCE現在捆綁在JDK中,所以區別變得不那么明顯了。由於JCE使用與JCA相同的體系結構,所以JCE應該更適合作為JCA的一部分。
JDK中的JCA包含兩個軟件組件:
1. 定義和支持提供者為其提供實現的加密服務的框架。這個框架包含了諸如java.security,javax.crypto,javax.crypto.spec和javax.crypto.interfaces等軟件包。
2.Sun,SunRsaSign,SunJCE等實際提供者都包含了具體的加密實現。
無論什么時候提及特定的JCA提供者,都可以找到與之對應的名稱。
設計原則:
JCA是圍繞這些原則設計的:
1.實現獨立性和互操作性
2.算法獨立性和可擴展性
實現獨立性和算法獨立性是互補的;您可以使用加密服務(如數字簽名和消息摘要),而無需擔心實現細節,甚至是構成這些概念基礎的算法。盡管完全的算法獨立性是不可能的,但JCA提供了標准化的,算法特定的API。當實現獨立性不可取時,JCA讓開發人員指出具體的實現。
通過定義密碼“引擎”(服務)的類型,並定義提供這些密碼引擎的功能的類來實現算法獨立性。這些類被稱為引擎類,例如MessageDigest,Signature,KeyFactory,KeyPairGenerator和Cipher類。
實現獨立性是使用基於“提供者”的體系結構實現的。術語密碼服務提供商(CSP)(在本文檔中與“提供商”可互換使用)是指實現一個或多個密碼服務(如數字簽名算法,消息摘要算法和密鑰轉換服務)的包或一組包。程序可以簡單地請求實現特定服務(例如DSA簽名算法)的特定類型的對象(例如簽名對象),並從一個安裝的提供者獲得實現。如果需要的話,程序可以改為請求來自特定提供者的實現。提供商可能會更新透明的應用程序,例如,當更快或更安全的版本可用。
實現互操作性意味着各種實現可以相互協作,使用彼此的密鑰,或者驗證彼此的簽名。這就意味着,例如,對於相同的算法,由一個提供者生成的密鑰可以被另一個提供者使用,並且由一個提供者生成的簽名可以被另一個提供者驗證。
算法可擴展性意味着可以容易地添加適合於所支持的引擎類之一的新算法。
加密服務提供者:
java.security.Provider是所有安全提供程序的基類。每個CSP都包含這個類的一個實例,它包含了提供者的名字,並列出了它實現的所有安全服務/算法。當需要特定算法的實例時,JCA框架會咨詢提供者的數據庫,如果找到合適的匹配項,則創建該實例。
提供者包含一個包(或一組包),為廣告的加密算法提供具體的實現。每個JDK安裝都默認安裝並配置了一個或多個提供程序。其他提供者可以靜態或動態添加(參見提供者和安全類)。客戶端可以配置其運行時環境來指定提供程序的首選順序。首選順序是在沒有請求特定提供者時提供者搜索請求的服務的順序。
要使用JCA,應用程序只需要請求特定類型的對象(如MessageDigest)和特定的算法或服務(如“SHA-256”算法),並從一個已安裝的提供者獲取實現。或者,程序可以請求來自特定提供者的對象。每個提供者都有一個名字來引用它。
md = MessageDigest.getInstance("SHA-256"); md = MessageDigest.getInstance("SHA-256", "ProviderC");
下圖說明了請求“SHA-256”消息摘要實現。這些圖顯示了實現各種消息摘要算法(“SHA-256”,“SHA-384”和“SHA-512”)的三個不同的提供者。提供者按照優先順序從左至右排列(1-3)。在第一個例子中,一個應用程序請求一個SHA-256算法實現而不指定提供者名稱。提供程序按優先順序搜索,並返回提供該特定算法ProviderB的第一個提供程序的實現。在第二個圖中,應用程序請求來自特定提供者ProviderC的SHA-256算法實現。這次ProviderC的實現被返回,即使具有更高優先級的提供者ProviderB也提供SHA-256實現。
JDK中的加密實現主要是出於歷史原因通過幾個不同的提供者(Sun,SunJSSE,SunJCE,SunRsaSign)分發的,但在較小的程度上由它們提供的功能和算法的類型來分發。其他Java運行時環境可能不一定包含這些Sun提供程序,因此除非知道特定的提供程序可用,否則應用程序不應請求提供程序特定的實現。
JCA提供了一組API,允許用戶查詢安裝哪些提供程序以及支持哪些服務。
提供者如何實際執行:
如前所述,通過定義所有應用程序用於訪問服務類型的通用高級應用程序編程接口(API)來實現算法獨立性。實現獨立性是通過使所有提供者實現符合定義良好的接口來實現的。引擎類的實例因此被具有相同方法簽名的實現類“支持”。應用程序調用通過引擎類路由,並傳遞到底層的后台實現。該實現處理請求並返回正確的結果。
每個引擎類中的應用程序API方法通過實現相應Service Provider Interface(SPI)的類路由到提供程序的實現。也就是說,對於每個引擎類,都有一個相應的抽象SPI類,它定義了每個加密服務提供者算法必須實現的方法。每個SPI類的名稱與相應的引擎類相同,接着是Spi。例如,簽名引擎類提供對數字簽名算法的功能的訪問。實際的提供者實現是在SignatureSpi的子類中提供的。應用程序調用引擎類的API方法,在實際的實現中又調用SPI方法。
每個SPI類都是抽象的。為了為特定算法提供特定類型的服務,提供者必須繼承相應的SPI類,並提供所有抽象方法的實現。
import javax.crypto.*; Cipher c = Cipher.getInstance("AES"); c.init(ENCRYPT_MODE, key);
SecureRandom
, MessageDigest
, Signature
, Cipher
, Mac
, KeyFactory
, SecretKeyFactory
, KeyPairGenerator
, KeyGenerator
, KeyAgreement
, AlgorithmParameters
, AlgorithmParameterGenerator
, KeyStore
, and CertificateFactory
, engine classes,
java.security
javax.crypto
java.security.cert
java.security.spec
javax.crypto.spec
java.security.interfaces
javax.crypto.interfaces
The Provider
Class
術語“加密服務提供者”(在本文檔中與“提供者”可互換使用)是指提供JDK安全API加密特征子集的具體實現的一個或一組包。 Provider類是這種包或一組包的接口。它具有訪問提供程序名稱,版本號和其他信息的方法。請注意,除了注冊加密服務的實現之外,Provider類還可以用於注冊可能被定義為JDK安全API或其擴展之一的其他安全服務的實現。
為了提供加密服務的實現,實體(例如開發組)編寫實現代碼並創建提供者類的子類。 Provider子類的構造函數設置各種屬性的值; JDK安全API使用這些值來查找提供者實現的服務。換句話說,子類指定實現服務的類的名稱。
不同的實現可能具有不同的特性。有些可能是基於軟件的,有些可能是基於硬件的。有些可能是平台無關的,有些可能是平台特定的。一些供應商的源代碼可能可用於審查和評估,而有些則可能不可用。 JCA讓最終用戶和開發者決定他們的需求。
在本節中,我們解釋最終用戶如何安裝符合他們需求的加密實現,以及開發人員如何請求適合他們的實現。
詳細參見:https://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html