来自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