java网络与安全java 安全java

Java加密体系结构(JCA)参考指南

2018-10-14  本文已影响140人  spraysss

JCA简介

Java平台强调安全性,包括语言安全性、密码学、公钥基础设施、身份验证、安全通信和访问控制。
JCA是java平台的重要部分,它包含了“provider”架构和一系列数字签名、消息摘要、证书和证书认证、加密(对称/非对称 流式/分组 加密),秘钥生成和管理、安全随机数生成API。这些API是的开发者可以十分简单的把安全集成到应用代码中。JCA架构设计上遵循如下准则:

JCA设计原则

JCA是围绕以下原则设计的

实现独立性和算法独立性是互补的;您可以使用加密服务,比如数字签名和消息摘要,而不用担心实现细节,甚至不用担心构成这些概念基础的算法。虽然不可能完全独立于算法,但是JCA提供了标准化的、特定于算法的api。当不需要实现独立性时,JCA允许开发人员指定特定的实现。

算法独立性是通过定义加密“引擎”(服务)类型和定义提供这些加密引擎功能的类来实现的。这些类称为引擎类,比如MessageDigest, Signature, KeyFactory, KeyPairGenerator, and Cipher

实现独立性是通过使用基于“provider”的体系结构来实现的。实现独立性是通过使用基于“提供者”的体系结构来实现的。加密服务提供者(CSP)与“provider”是两个等价的术语,(请参阅加Cryptographic Service Providers
)指实现一个或多个加密服务的包或一系列包,如数字签名算法、消息摘要算法和密钥转换服务。程序可以简单地请求实现特定服务(如DSA签名算法)的特定类型的对象(如签名对象),并从安装的providers实现中选择一个。
实现互操作性意味着各种实现可以相互协作、使用彼此的密钥或验证彼此的签名。例如,对于相同的算法,一个provider生成的密钥可以被另一个provider使用,一个provider生成的签名可以被另一个provider验证。
算法的可扩展性意味着可以很容易地添加适合支持引擎类的新算法。

Provider架构

Providers包含一个包(或一组包),它为公开的加密算法提供具体的实现。
CSP
java.security.Provider是所有Provider的基类。每个CSP都包含该类的一个实例,该实例包含provider的名称,并列出它实现的所有安全服务/算法。当需要特定算法的实例时,JCA框架会查询provider的数据库,如果找到了合适的匹配,就会创建实例。
Provider包含一个包(或一组包),它为公开的加密算法提供具体的实现。JDK在安装时会自带一个或多个provider,可以静态或动态添加其他provider。客户机可以配置其运行时环境来指定provider优先序,当没有指定特定的provider时, provider按照优先序返回第一个搜索到的provider。
要使用JCA,应用程序只需请求特定类型的对象(如MessageDigest)和特定的算法或服务(如“SHA-256”算法),并从安装的provider之一获得实现。例如,以下语句从已安装的provider请求SHA-256消息摘要:

  md = MessageDigest.getInstance("SHA-256");

或者,程序可以指定provider。每个provider都有一个用于引用它的名称。例如,以下语句从名为ProviderC的provider请求SHA-256消息摘要:

 md = MessageDigest.getInstance("SHA-256", "ProviderC");

下面的图说明了请求SHA-256消息摘要实现。它们显示了三个不同的provider,它们实现了各种消息摘要算法(SHA-256、SHA-384和SHA-512)。provider优先序从左到右递减。在图2-1中,应用程序不指定provider名称请求SHA-256算法实现,按照优先顺序搜索provider会返回ProviderB。在图2-2中,应用程序从特定的提供者ProviderC请求SHA-256算法实现。这一次会返回ProviderC的实例,即使具有更高优先级顺序的提供者ProviderB也提供MD5实现。

图2-1没有指定提供程序的请求SHA-256消息摘要实现

2-1
图2-2使用ProviderC请求SHA-256消息摘要
2-2
JDK中的加密实现是通过几个不同的provider(Sun、SunJSSE、SunJCE、SunRsaSign)分发的,这主要是由于历史原因,但在较小程度上是由于它们提供的功能类型和算法。其他Java运行时环境可能不一定包含这些provider,因此应用程序不应该请求特定于provider的实现,除非知道某个特定provider是可用的。
JCA提供了一组api,允许用户查询安装了哪些provider以及它们支持哪些服务。
这种体系结构还使最终用户可以很容易地添加其他provider。许多第三方provider实现已经可用。有关provider如何编写、安装和注册的详细信息,请参阅Provider 类

provider是如何实现的
算法独立性是通过定义一个通用的高级应用程序编程接口(API)来实现的,所有应用程序都使用这个API来访问服务类型。实现独立性是通过让所有的provider实现遵守定义好的接口。比如引擎类,应用程序调用通过engine类路由并传递到底层的支持实现。实现处理请求并返回正确的结果。

每个引擎类中的应用程序API方法通过实现相应服务provider接口(SPI)的类路由到provider的实现。也就是说,对于每个引擎类,都有一个相应的抽象SPI类,它定义了每个加密服务provider的算法必须实现的方法。每个SPI类的名称与相应引擎类的名称相同,后面跟着SPI。比如, Signature 签名引擎提供了数字签名的功能, 实际provider 需要实现的SPI为SignatureSpi,应用程序调用engine类的API方法,后者在实际实现中调用SPI方法。
每个SPI类都是抽象的。要为特定算法提供特定类型服务的实现,Provider必须子类化相应的SPI类,并为所有抽象方法提供实现。
对于API中的每个引擎类,通过调用引擎类中的getInstance()工厂方法来请求和实例化实现实例。引擎类使用上面描述的框架provider选择机制来获得实际的支持实现(SPI),然后创建实际的引擎对象。engine类的每个实例都封装了相应SPI类的实例(作为私有字段),即SPI对象。API对象的所有API方法都声明为final,它们的实现调用封装的SPI对象的相应SPI方法。
为了更清楚地说明这一点,请看示例2-1和图2-3:

示例2-1 获取Engine类实例的示例代码

  import javax.crypto.*;

    Cipher c = Cipher.getInstance("AES");
    c.init(ENCRYPT_MODE, key);

图2-3 应用程序检索“AES”密码实例

2-3

如图所示应用需要一个javax.crypto.Cipher.AES的实例而不关心使用哪一个provider。应用程序调用Cipher engine类的getInstance()工厂方法,该方法要求JCA框架找到第一个支持AES的provider实例。框架咨询每个已安装的provider,并获得provider类的provider实例。(回想一下,Provider类是可用算法的数据库。)框架搜索每个provider,最后在CSP3中找到合适的条目。这个数据库入口指向扩展了CipherSpi的com.foo.AESCipher实现类,因此适用于Cipher engine。com.foo.AESCipher实例创建并封装在新创建的javax.crypto.Cipher实例中.当应用程序现在对Cipher实例执行init()操作时,Cipher engine类将请求路由到com.foo.AESCipher中的相应engineInit()方法。
Java Security Standard Algorithm Names列出为Java安全环境定义的标准名称。其他第三方provider可能会定义自己的这些服务的实现,甚至是附加服务。

Keystores(密钥存储库)

所谓keystore是一个可以用来管理密钥和证书的数据库。对于需要数据进行身份验证、加密或签名的应用程序,可以使用密钥存储库
应用程序可以使用java.security包中的 KeyStore 的实现类来访问一个秘钥存储库。在JDK 9中,默认和推荐的密钥存储类型(格式)是“pkcs12”,它基于RSA pkcs12个人信息交换语法标准。在此之前,默认的密钥存储类型是“jks”,这是一种专有格式。还可以使用其他密钥存储格式,例如“jceks”(另一种专用密钥存储格式)和“pkcs11”(基于RSA pkcs11标准),支持访问加密令牌,如硬件安全模块和智能卡。
应用程序可以从不同的提供者中选择不同的密钥存储实现。

引擎类和算法

engine类为特定类型的加密服务提供接口,独立于特定的加密算法或provider

引擎提供以下之一:

引擎类:

核心类和接口

以下是JCA中提供的核心类和接口。

本指南将首先介绍最有用的高级类(Provider, Security, SecureRandom, MessageDigest, Signature, Cipher, and Mac),然后深入研究各种支持类。现在,只需简单地说键(public, private, and secret)是由各种JCA类生成和表示的,高级类将其用作操作的一部分就足够了。
本节展示了每个类和接口中的主要方法,这些类(MessageDigest, Signature, KeyPairGenerator, SecureRandom, KeyFactory, 和key specification classes) 中的一些示例在相应的代码示例部分中提供

有关安全API包的完整参考文档可以在包摘要中找到:

Provider 类

未完待续

上一篇下一篇

猜你喜欢

热点阅读