java网络学习之 jca体系概述(12)

java安全体系包括以下:JCA、JCE、JSSE、JAAS、JGSS、SASL

jca 概述

JCA主要包含了多个服务分别用于数字签名,消息摘要(哈希),证书和证书验证,加密(对称/非对称块/流密码),密钥生成 管理和安全随机数生成等等。jca服务的使用是基于jca 的多个引擎类,这些引擎类实现了对应的服务接口,引擎类好似一个路由,它内部会去遍历providers,查找对应的算法并返回。java 提供了一个Provider 接口, 所有人都可以自定义provider 实现,然后注册到java.security 中就可以了。

在jca 体系中 客户端直接使用的是服务,而服务的实现可以基于多个逻辑实现(算法),并且服务可以由多家供应商提供,所以获取一个服务其实 需要两个参数 算法和供应商,如果不指定供应商,则按顺序找到第一个就返回了。

JCA框架定义了服务接口和provider接口,JCE包里包含了很多供应商如Sun,SunRsaSign,SunJCE等。

java 内置的供应商实现由于美国出口限制,所以算法实现没有那么精密,只给出了比较简单的算法实现。如果要使用比较精密的算法实现,可以添加其他供应商。例如 bouncy castle和apache common codec,它们提供了额外的算法以及在JDK基础上提高了易用性

术语

  • JCE(Java Cryptography Extension),在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。现在JCE已经捆绑在JDK中,所以,这里JCE是JCA的一部分。

设计原则

  • 实现独立性和互操作性
  • 算法独立性和可扩展性

JCA提供标准化的、算法特定的API来实现上面两个原则。

  1. 通过各种引擎类来实现不同的功能,实现算法独立性(例如MessageDigest,Signature,KeyFactory,KeyPairGenerator和Cipher类)
  2. 使用Provider(提供者)的体系结构来达到“实现独立性”,程序可以指定使用特定服务提供者的算法实现。
  3. 实现互操作性意味着各种实现可以相互协作,使用彼此的密钥,或者验证彼此的签名。 这就意味着,对于相同的算法,由一个提供者生成的密钥可以被另一个提供者使用,并且由一个提供者生成的签名可以被另一个提供者验证。

核心包

JCA相关安全API软件包:

provider 提供者

provider提供者,这里的全称是 Cryptographic Service Provider (CSP),是指实现一个或多个密码服务(如数字签名算法,消息摘要算法和密钥转换服务)的包或一组包。 每个JDK安装都默认安装并配置了一个或多个provider包。用户可以静态或动态添加其他provider。
JDK中的加密库出于历史原因,由几个不同的提供者实现:

  • Sun
  • SunJSSE
  • SunJCE
  • SunRsaSign

java.security.Provider是所有安全提供程序的基类。
 

如何自己定provider?

为了提供密码服务的实现,一个实体(例如开发组)编写实现代码并创建Provider类的子类。 Provider子类的构造函数设置各种属性的值; JDK安全API使用这些值来查找提供者实现的服务。 换句话说,子类指定实现服务的类的名称。

Provider实现

 

JCA实现原理(引擎类路由和provider 架构)

JCA使用引擎类作为路由,来实现java开发者和底层Provider实现的关联,实现实现独立性。

  • 引擎类:每个引擎类,都有一个对应的抽象SPI类,它定义了每个加密服务提供者算法必须实现的方法。
  • SPI(服务提供者接口):每个SPI类的名称与相应的引擎类相同,接着是Spi。 例如,Signature引擎类提供对数字签名算法的功能的访问。 实际的提供者实现是在SignatureSpi的子类中提供的。 应用程序调用引擎类的API方法,在实际的实现中又调用SPI方法。

下面的案例,展示了引擎类的使用,获取Provider对象实例的过程:
例如

import javax.crypto.*;
Cipher c = Cipher.getInstance("AES");
c.init(ENCRYPT_MODE, key);

  1. 这里的应用程序需要一个“AES”算法的javax.crypto.Cipher实例,并不关心使用哪个提供者。
  2. 应用程序调用Cipher引擎类的getInstance()工厂方法,然后请求JCA框架查找支持“AES”的第一个提供程序实例。
  3. 该框架会咨询每个已安装的提供者,并获取提供者类的提供者实例。框架搜索每个提供者,最终在CSP3中找到合适的条目。
  4. 这个数据库入口指向扩展CipherSpi的实现类com.foo.AESCipher,因此适用于Cipher引擎类。创建一个com.foo.AESCipher的实例,并将其封装在一个新创建的javax.crypto.Cipher实例中,该实例返回给应用程序。
  5. 当应用程序现在对Cipher实例执行init()操作时,Cipher引擎类将请求路由到com.foo.AESCipher类中相应的engineInit()支持方法中。

引擎类

引擎类为特定类型的密码服务提供接口,而不依赖于特定的密码算法或提供者。 引擎需要提供:

  • 密码操作(加密,数字签名,消息摘要等)(下文红色部分)
  • 发生器或密码材料的转换器(密钥和算法参数) (下文绿色部分)
  • 对象(密钥库或证书)封装了密码数据,可以在更高的抽象层使用。(下文蓝色部分)

以下引擎类是可用的:

  • SecureRandom:用于生成随机或伪随机数字。
  • MessageDigest:用于计算指定数据的消息摘要(散列)。
  • Signature:使用密钥初始化,这些签名用于签署数据并验证数字签
  • Cipher:用密钥初始化,用于加密/解密数据。存在各种类型的算法:对称批量加密(例如AES),非对称加密(例如RSA)和基于密码的加密(例如PBE)。
  • Message Authentication Codes(MAC):与MessageDigests一样,它们也会生成散列值,但是首先使用密钥初始化以保护消息的完整性。
    KeyFactory:用于将Key类型的现有不透明密钥转换为密钥规范(底层密钥材料的透明表示),反之亦然。
    SecretKeyFactory:用于将SecretKey类型的现有不透明加密密钥转换为密钥规范(底层密钥材料的透明表示),反之亦然。
    KeyPairGenerator:用于生成一对适用于指定算法的公钥和私钥。
    KeyGenerator:用于生成与指定算法一起使用的新密钥。
    KeyAgreement:由两方或多方使用,商定和建立一个特定的密钥,用于特定的密码操作。
    AlgorithmParameters:用于存储特定算法的参数,包括参数编码和解码。
    AlgorithmParameterGenerator:用于生成适合于指定算法的一组AlgorithmParameters。
    KeyStore:用于创建和管理密钥库。密钥库是密钥的数据库。密钥库中的私钥具有与其关联的证书链,用于验证相应的公钥。密钥库还包含来自可信实体的证书。
    CertificateFactory:用于创建公钥证书和证书吊销列表(CRL)。
    CertPathBuilder:用于构建证书链(也称为证书路径)。
    CertPathValidator:用于验证证书链。
    CertStore:用于从存储库中检索证书和CRL。

注意:生成器可以创建具有全新内容的对象,而工厂只能从现有材料(例如编码)中创建对象。

 

JCA 常用类简单介绍

1. Provider类

  • 指定Provider类
    在调用引擎类的getInstance方法来请求和实例化实现实例时,指定想要实现的所需算法的名称以及可选的Provider(或提供者类)的名称。
  • 安装Providers
    有两种方式安装Provider:1 在classpath的任何位置放置一个包含Provider类的zip或JAR文件;2将程序置于标准扩展目录中,则该提供程序将被视为已安装的扩展程序
  • 注册Provider
    静态注册:在配置文件JAVA_HOME\lib\security\java.security中注册security.provider.n=masterClassName
    动态注册:调用Security类中的addProvider或insertProviderAt方法。
  • Provider类方法
    public String getName()
    public double getVersion()
    public String getInfo()

2. Security类

Security类管理已安装的提供程序和安全性属性。 它只包含静态方法,永远不会实例化。
提供了一系列API查询Provider、增加Provider、删除Provider

Provider[] arr = Security.getProviders();

3. SecureRandom随机生成器类

SecureRandom类是提供随机数生成器(RNG)功能的引擎类。 它不同于java.lang.Random类,因为它产生密码强的随机数。 如果生成器中的随机性不足,则会使保护机制变得更加容易。 在密码学中使用随机数字,例如生成加密密钥,算法参数等等。

4. MessageDigest摘要类

MessageDigest类是一个引擎类,用于提供密码安全的消息摘要(如SHA-256或SHA-512)的功能。 加密安全的消息摘要采用任意大小的输入(一个字节数组),并生成一个固定大小的输出,称为摘要或散列。

 

 

5. Signature 签名类

Signature类是一个引擎类,旨在提供加密数字签名算法(如DSA或RSAwithMD5)的功能。 密码安全签名算法采用任意大小的输入和私钥,并生成一个相对较短(通常是固定大小)的字节串,称为签名,具有以下属性:

  • 只有私钥/公钥对的所有者才能创建签名。 任何拥有公钥的人都可以在计算上不可能恢复私钥
  • 鉴于与用于生成签名的私钥相对应的公钥,应该有可能验证输入的真实性和完整性。
  • 签名和公钥没有透露有关私钥的任何信息。

     

     

6. Cipher 加密解密类

Cipher类提供用于加密和解密的加密密码的功能。 加密是取数据(称为明文)和密钥的过程,并且产生对不知道密钥的第三方毫无意义的数据(密文)。 解密是相反的过程:取密文和密钥并产生明文。

 

 

7. SealedObject 密封对象类

这个类使程序员能够用密码算法创建对象并保护其机密性。

给定任何实现了java.io.Serializable接口的对象,可以使用密码算法创建一个封装原始对象的SealedObject,以序列化格式(即“深层复制”)封装原始对象,并封装(加密)其序列化内容 如AES,以保护其机密性。 加密的内容稍后可以被解密(使用正确的解密密钥的相应算法)并且解序列化,产生原始对象。

8. Mac 消息认证码类

HMAC是基于密码散列函数实现的MAC,是MAC的一种。 HMAC使用密码散列函数(例如SHA-256)算法 ,然后结合共享密钥使用。

 

9. Key 密钥接口

秘钥有两种表示形式:key(不透明)和keyspecs(透明)。

  • 不透明的密钥接口无法直接访问密钥材料字段,只有定义的三种方法:getAlgorithm,getFormat和getEncoded。
  • 透明的密钥,可以以通过相应规范类中定义的某个get方法单独访问每个关键字值。 例如,DSAPrivateKeySpec定义了getX,getP,getQ和getG方法来访问私钥x以及用于计算密钥的DSA算法参数:素数p,次数q和基数g。 如果密钥存储在硬件设备上,其规格可能包含有助于识别设备密钥的信息。

9.1 Key 不透明秘钥接口

秘钥可以通过以下方式获得:

  • KeyGenerator (生成对称秘钥)
  • KeyPairGenerator(生成非对称秘钥)
  • Certificate证书
  • KeyStore密码库
  • 转换KeySpecs(使用KeyFactory)

java.security.Key接口是所有不透明密钥的顶层接口。
以下是在java.security.interfaces和javax.crypto.interfaces包中扩展Key接口的接口列表:

SecretKey用于对称秘钥
PublicKey和PrivateKey接口分别用于非对称秘钥的公钥和私钥。
KeyPair类是密钥对(公钥和私钥)的简单持有者。

9.2 KeySpecs 透明秘钥接口

也叫密钥规范(密钥材料)接口
java.security.spec包中的密钥规范接口和类。
DESKeySpec是一种DES密钥规范。
X509EncodedKeySpec是一种公钥编码规范,它表示公钥的DER编码,根据X.509标准中规定的格式。
PKCS8EncodedKeySpec是一种私钥编码规范,以PKCS8标准中指定的格式对私钥进行DER编码。

KeySpecs实现的子类如下:

10 生成器和工厂类的区别:

10.1 生成器 **Generator

生成器用于生成一个全新的对象(秘钥)。比如KeyGenerator生成SecretKey,KeyPairGenerator生成KeyPair。
生成器一般有两种方法来生成密钥对

  • 以独立于算法的方式

void initialize(int keysize, SecureRandom random)
void initialize(int keysize)

  • 以特定于算法的方式

void initialize(AlgorithmParameterSpec params, SecureRandom random)
void initialize(AlgorithmParameterSpec params)

KeyPairGenerator类,用于生成公钥和私钥对的引擎类。

 

KeyGenerator类, 用于为对称算法生成密钥。

 

10.2 工厂类 **Factory

工厂类用于将数据从一个现有的对象类型转换为另一个。一个密钥工厂可以用来在兼容的密钥规范之间进行转换。
比如SecretKeyFactory和KeyFactory,可以转换keySpecs为key。比如CertificateFactory,从字节输入流(FileInputStream)转换成证书(Certificate)对象。

秘钥工厂是双向的,密钥工厂用于将密钥(java.security.Key类型的不透明密钥)转换为密钥规范(以合适的格式对基础密钥材料进行透明表示),反之亦然。
比如KeyFactory类和SecretKeyFactory类:

 

 

11 KeyAgreement 秘钥协商类

Diffie-Hellman算法是一种密钥协议,是两方或多方可以建立相同密码密钥而不必交换任何秘密信息的协议。

 

 

生成共享密钥有如下几步:

  1. 创建KeyAgreement对象

KeyAgreement.getInstance()

  1. 初始化KeyAgreement

public void init(Key key);
public void init(Key key, SecureRandom random);
public void init(Key key, AlgorithmParameterSpec params);
public void init(Key key, AlgorithmParameterSpec params, SecureRandom random);

  1. 执行密钥协商阶段

public Key doPhase(Key key, boolean lastPhase);

  1. 生成共享密钥

public byte[] generateSecret();
public int generateSecret(byte[] sharedSecret, int offset);
public SecretKey generateSecret(String algorithm);

12. 密码库KeyStore

“密钥库”是一种可用于管理密钥和证书的存储库,一个密码库包含多个私钥和证书。

  • KeyStore文件:用户密钥库默认存储在用户主目录中名为.keystore的文件中。
  • 密码库工具:keytool和jarsigner的命令行工具,以及一个名为policytool的基于GUI的工具。
  • 密钥库实现类型:
    默认的keystore实现类型是“jks”,
    推荐的keystore实现是“pkcs12”,
    可以在java.security文件中的修改默认实现类型:
    keystore.type=jks

KeyStore类

 

密钥库中有两种不同类型的条目:Key Entry(密钥条目)和Trusted Certificate Entry(可信任的证书条目)
KeyStore对象可以从文件中load()或store()到文件。并提供了一系列方法来操作key条目和Certificate条目。

KeyStore 一个安全的,用于存储密码和可信证书的仓库。

CertStore 用于存储不相关的,不受信的证书。同样它可以存储CRLs。

13. AlgorithmParameters和AlgorithmParameterSpecs

AlgorithmParameters:不透明的加密参数接口
AlgorithmParameterSpecs:透明的加密参数接口
AlgorithmParameters或AlgorithmParameterSpecs用于配置算法的初始化参数
AlgorithmParameterGenerator生成器,是一个引擎类,用于生成一组适用于特定算法的全新参数,提供了生成AlgorithmParameters和AlgorithmParameterSpecs的方法。

14. CertificateFactory类

CertificateFactory类是定义证书工厂功能的引擎类,用于从其编码(文件流)生成证书和证书吊销列表(CRL)对象。

15. JCA如何在SSL / TLS实现中使用

  1. 使用KeyManager(密钥库)和TrustManagerSSLContext(信任度)初始化SSLContext
  2. 使用上下文SSLContext,创建实际实现SSL / TLS协议的对象(SSLSocket和SSLEngine)。
  3. SSLSocket和SSLEngine将直接在通信对象中使用。

KeyManager和TrustManager作用:

  • JSSE KeyManager负责向对等端显示使用的凭证(使用的密码标准、加密算法、证书、公钥、签名等)
  • JSSE TrustManager负责验证从对等端收到的凭证,验证凭证有多种方式:其中之一是创建CertPath对象,并让JDK的内置公钥基础结构(PKI)框架处理验证。 在内部,CertPath实现可能会创建一个Signature对象,并使用它来验证证书链中的每个签名。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值