在JCA中分别有几种不同的类:Engine类,SPI类,Provider类。一下会分别解释这几种类的作用以及关系。
Engine类
Engine类是供外部使用某种特定服务的类。比如,用于消息摘要的MessageDigest类;用于生成随机数的SecureRandom类;用于加密的Cipher类等等。它并不完成具体的功能,而是将所有的操作,通过方法调用的方式,转发到它所依赖的Spi类中,并由Spi类来完成功能。
在使用Engine类的时候有一些通用的规则:
- Engine类无法直接通过构造方法来实例化。只能通过调用其静态的getInstance方法获得实例。调用getInstance方法时,需要一个算法名称和一个可选的Provider。
- 拿到Engine类的实例之后,可能需要调用它的Init方法(根据不同的Engine类可能有不同Init方法),对这个Engine对象进行初始化。不同的Engine类,需要不同的初始化参数。
- 调用特定Engine相关的一些方法,执行需要的操作。这一步差异较大,具体情况,具体分析。(doFinal, digest 等...)
SPI(Service Provider Interface) 类
提供某种服务的特定算法实现。他们都继承了对应的XxxSpi接口。比如,采用MD5算法进行消息摘要的MD5类和采用SHA256算法进行消息摘要的SHA2类,继承了MessageDigestSpi;采用AES算法进行数据加密的AESCipher类和采用DES算法进行数据加密的DESCipher类,继承了CipherSpi。
根据上面Engine类的描述,Engine类会把实际的操作委托给SPI类来完成。
Provider类
首先要区分下Provider和Provider类。实际上可以将Provider理解为一个或一组jar包。这些jar包中包含了一些实现好的SPI类。这些jar包可能是Java安装包中自带的,也可能是某些组织为了使用一些特定的算法,而自己开发的,也可能是从网上下载的第三方jar包。无论渠道是怎样的,每一组jar包就称为一个 Provider。那么Provider类就是用于描述和初始化这个Provide的。比如告知JCE这个Provide中提供了哪些服务,以及实现了特定服务的哪些算法等。因此每一组可以被称为Provider的jar包中,都会包含一个用于描述这个Provider的Provider类。
Engine/SPI/Provider之间的关系
- Provider类描述了Provider本身(name, version...),以及它所包含的SPI,JCA会从Provider类中获取这些信息;
- Engine类依赖于SPI类来完成功能,每一个Engine类内部都会有一个以Spi结尾的属性。Engine类就是通过这个对象来调用Spi中的方法的;
- 当向JCA请求一个Engine时(调用getInstace),JCA会根据请求时的参数,并根据Provider类中提供的信息,找到对应的SPI类,并实例化之。将SPI对象装配到Engine对象中返回。从而供外部调用Engine类中的方法时,进行操作转发。
在JDK的安装文件中,包含了11个内置的Provider:SunPKCS11, SUN, SunRsaSign, SunJSSE, SunJCE, SunJGSS, SunSASL, XMLDSig, SunPCSC, SunMSCAPI, SunEC。关于每种Provider中提供了什么服务,请参见Java的官方文档。
这就是JCA的一个简单的描述,只有正确理解了这个通用的架构,才能更好的理解Java Security。
No comments :
Post a Comment