版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java™加密体系结构
API规范和参考
2011年01月30日
简介
[设计原理]
[体系结构]
核心类和接口
[Provider类]
如何请求和提供提供者的实现
安装提供者
[Sercuity类]
[MessageDigest类]
[Signature类]
[算法参数类]
算法参数规范接口和类
[AlgorithmParameterSpec接口】
[DSAParameterSpec类】
Algorithmparameters类
AlgorithmParameterGenerator类
[密钥接口]
[密钥规范接口和类]
KeySpec接口
DSAPrivateKeySpec类
DSAPublicKeySpec类
RSAPrivateKeySpec类
RSAPrivateCrtKeySpec类
RSAPublicKeySpec类
EncodedKeySpec类
PKCS8EncodedKeySpec类
X509EncodedKeySpec类
[KeyFactory类]
[CertificateFactory类]
[KeyPair类]
[KeyPairGenerator类]
[密钥管理]
Keystore位置
Keystore实现
KeyStore类
[SecureRandom类]
代码示例
[计算MessageDigest对象]
[生成密钥对]
[用生成的密钥来生成和校验签名]
[用密钥规范和KeyFactory来生成和校验签名]
[读取用Base64编码的证书]
[解析证书答复]
附录A:标准名称
附录B:算法
简介
JDK安全API是Java编程语言的核心API,位于java.security包(及其子包)中。该API设计用于帮助
开发人员在程序中同时使用低级和高级安全功能。
JDK1.1中第一次发布的JDK安全中引入了“Java加密体系结构”(JCA),指的是用于访问和开发Java平台
密码功能的构架。在JDK1.1中,JCA包括用于数字签名和报文摘要的APIo
正如本文档所述,JDK1.2大大扩展了Java加密体系结构。它还对证书管理基础结构进行了升级以支持
X.509V3证书,并为划分细致、可配置性强、功能灵活、可扩展的访问控制引入了新的Java安全体系结构。
Java加密体系结构包含JDK1.2安全API中与密码有关的部分,以及本文档中提供的一组约定和规范。为
实现多重、可互操作的密码,它还提供了“提供者”体系结构。
Java密码扩展(JCE)扩展了JCAAPI,包括用于加密、密钥交换和信息认证码(MAC)的API„JCE和JDK密
码共同提供了一个与平台无关的完整密码API。JCE作为JDK的扩展将独立发布,以符合美国的出口控制
约束。
本文档是对Java开发工具包(JDK)1.2版中发布的Java加密体系结构API及其缺省提供者的描述和说明。
描述JCEAPI的文档将在JCE版本中提供。有关JDK安全API中Java安全体系结构方面的信息,参见
“Java安全体系结构规范”。
注:该JCA规范的最新版本可在公共网站
http://java.sun.eom/products/jdk/l.2/docs/guide/security/CryptoSpec.html上找到。
设计原理
Java加密体系结构(JCA)是根据以下原理设计的:
•实现的独立性和互操作性
•算法的独立性和可扩展性
实现的独立性和算法独立性是互补的:其目的是让API用户能用密码学的概念(如数字签名和报文摘要),
但又不必关心这些概念的实现甚至实现这些概念所用算法的实现。当不可能完全实现算法独立性时,JCA将
为开发人员提供标准的特定算法APL当实现方法的独立性不可能实现时,JCA将让开发人员指明所要求的
特定实现方法。
算法独立性是通过定义密码“引擎”(服务)的类型以及定义提供这些密码引擎功能的类来实现的。这些类
称为engine(引擎)类,例如MessageDigest类、Signature类和KeyFactory类。
实现的独立性是通过使用基于“提供者”的体系结构而实现的。密码服务提供者(简称“提供者”)指的是
用于实现一种或多种密码服务的一个包或一组包,如数字签名算法、报文摘要算法及密钥交换服务。程序
可以只是简单地请求某类对象(如签名对象)实现某种服务(如DSA数字签名算法),并从任一安装好的
提供者上获取实现方法。反之,必要时程序可从某个特定的提供者那请求实现方法。当有更快或更安全的
版本可用时,提供者的升级对应用程序来说是透明的。
实现的互操作性指的是各种实现方法可在一起工作,使用彼此的密钥或校验彼此的签名。这意味着对于相
同的算法,由一个提供者生成的密钥可被另一个提供者使用,而一个提供者生成的签名也可由另一个提供
者来校验。
算法的可扩展性指的是可以很容易地添加那些能适应所支持的engine类的新算法。
体系结构
密码服务提供者
Java加密体系结构引入了密码服务提供者(简称为“提供者”)的概念。它是指一个(或一组)包,用于
提供JDK安全API的密码子集的具体实现。
例如,在JDK1.1中,提供者可包含一个或多个数字签名算法、报文摘要算法及密钥生成算法的实现。JDK1.2
增加了五类附加服务:密钥工厂、密钥仓库的创建与管理;算法参数管理;算法参数的生成和证书工厂。
它还允许提供者提供随机数生成(RNG)算法。在以前的版本中,RNG不是由提供者提供的,而是某一特定
的算法嵌入在JDK中的。
如前所述,程序可以只是简单地请求某类对象(如Signature对象)提供某种服务(如DSA签名算法),
并从某一安装好的提供者上获取该对象的实现方法。程序也可请求某一特定的提供者(每个提供者都有自
己的名称,供引用时使用)。
Sun版本的Java运行时环境都带有一个名为“SUN”的缺省标准提供者。其它的Java运行时环境可能不
一定提供“SUN”提供者。“SUN”提供者包包括:
•一个数字签名算法(DSA)的实现,在NISTFIPS186中描述。
•一个MD5(RFC1321)和SHA-1(NISTFIPS180-1)报文摘要算法的实现。
•一个DSA密钥对的生成器,用于生成与该DSA算法相匹配的公钥和私钥对。
•一个DSA算法参数生成器。
•一个DSA算法参数管理器。
•一个DSA“密钥工厂”,用于提供(不透明)的DSA私钥对象和公钥对象及其所含的密钥信息之间
的双向转换。
•一个符合IEEEP1363标准(见附录G.7)的专用“SHA1PRNG”伪随机数生成算法的实现。
•一个为X.509证书和证书撤消清单(CRL)服务的“证书工厂”•
•一个用于名为“JKS”的专用密钥仓库类型的密钥仓库实现。
每个JDK安装都将安装一个或多个提供者包。新的提供者可以以动态或静态方式添加进来(参见Provider
和Security类)。Java加密体系结构提供了一组可供用户查询安装有哪些提供者及这些提供者支持哪些服
务的API。
客户可用不同的提供者配置他们的运行环境,并为每个提供者指定一个优先顺序。优先顺序是在未请求某
一指定提供者时根据所请求的服务对提供者进行搜索的顺序。
密钥管理
可使用一个叫做“密钥仓库”的数据库来管理密钥和证书。
应用程序可使用密钥仓库来完成认证或签名。
应用程序可通过实现java.security包中的KeyStore类来访问密钥仓库。SunMicrosystems提供了一个缺省
Keystore实现方法。它利用一个名为“JKS”的专用密钥仓库类型(格式),将密钥仓库实现为一个文件。
通过使用KeyStore类中提供的“getlnstance”方法,应用程序可从不同的提供者中选择不同类型的密钥仓
库实现方法。
有关详细信息,参见密钥管理一节。
概念
本节介绍API中引入的一些主要概念。
引擎类和算法
一个“引擎类”以一种抽象方式(无具体的实现方法)定义一种密码服务。
密码服务总是与某个特定的算法或类型相关联,它或者提供密码运算(如数字签名或报文摘要中的运算),
生成或提供密码运算所需要的密码信息(密钥或参数),或者生成安全封装的密钥(这些密钥可用于密码运
算中)的数据对象。例如,Signature和KeyFactory类就是两个引擎类。Signature类提供对数字签名算法
功能的访问。DSAKeyFactory以一种可供DSASignature对象的initSign或initVerify方法使用的格式提供
DSA私钥或公钥(从其编码或透明规范中)。
Java加密体系结构包含了JDK1.2安全包中与密码有关的类,包括引擎类。API用户可通过请求和利用引
擎类的实例来执行相应的运算。JDK1.2中定义了以下引擎类:
,MessageDigest—用于计算数据的报文摘要(散列)。
.Signature一用于对数据进行签名和校验数字签名。
•KeyPairGenerator一用于生成与指定算法相匹配的公钥和私钥对。
•KeyFactory一用于将类型为Key(密钥)的不透明密钥转换为密钥规范(密钥信息的透明表示),反
之亦然。
,CertificateFactory用于创建公钥证书和证书撤消清单(CRL)。
•KeyStore一用于创建和管理密钥仓库。密钥仓库是密钥的数据库。密钥仓库中的私钥有一个与之关
联的证书链,用于认证对应的公钥。密钥仓库还含有来自可信实体的证书。
•Algorithmparameters一用于管理某一特定算法的参数,包括编码和解码参数。
,AlgorithmParameterGenerator一用于生成一组与指定算法相匹配的参数。
,SecureRandom—用于生成随机数或伪随机数。
注意:“生成器”将创建新对象,而“工厂”将从现有信息(如某个编码方法)中创建对象。
一个引擎类提供某类密码服务功能的接口(与特定的密码算法无关)。它定义“应用程序接口”(API)方法,
以使应用程序能够访问所提供的某类密码服务。实际的实现方法(由一个或多个提供者提供)即是那些指
定算法的实现。例如,Signature引擎类将提供对数字签名算法功能的访问。SignatureSpi子类中(参见下
一段落)所提供的实际实现方法将是某个指定签名算法(如带有DSA的SHA1、带有RSA的SHA1或带
有RSA的MD5)的实现。
引擎类所提供的API是用“服务提供者接口”(SPI)来实现的。也就是说,对每一个引擎类,都有一个对
应的抽象SPI类,它定义了密码服务提供者必须实现的服务提供者接口方法。
作为引擎类的实例,“API对象”封装(作为private域)了对应的SPI类的实例,即“SPI对象”。API对
象的所有API方法都被声明为“final”,且其实现方法调用了所封装的SPI对象的相应SPI方法。调用某
个引擎类的getlnstancefactory方法将创建该引擎类(及其对应的SPI类)的实例。
SPI类的名称与对应的引擎类名称相同,后跟“Spi”。例如,与Signature引擎类相对应的SPI类是
SignatureSpi类。
每个SPI类都是抽象的。要实现某一指定算法的某一特定类型的服务,提供者必须对相应的SPI类进行子
类化并提供所有抽象方法的实现。
另一个引擎类的例子是MessageDigest类,它提供对报文摘要算法的访问。它在MessageDigestSpi子一类中
的实现可以是诸如SHA-1、MD5或MD2各种报文摘要算法的实现。
最后一个例子:KeyFactory引擎类支持将不透明密钥转换为透明密钥的规范,反之亦然(参见密钥规范接
口和类一节)。KeyFactorySpi子类中提供的实际实现将是指定类型的密钥(如DSA公钥和私钥)的实现。
实现和提供者
各种密码服务的实现由JCA密码服务提供者提供。提供者实际上是那些可提供一个或多个密码服务实现的
包。例如,Java开发工具包(JDK)的缺省提供者名为“SUN”,它可提供下述算法的实现:DSA签名算法、
MD5和SHA-1报文摘要算法、DSA密钥对生成算法和SHA1PRNG伪随机数生成算法。它还为DSA私钥
和公钥提供密钥工厂,为X.509证书和CRL提供证书工厂,并提供DSA参数(包括其生成)的实现,同
时也可为名为“JKS”的专用密钥仓库类型提供密钥仓库的实现。
其它提供者也可能已为这些服务或其它服务(如某个基于RSA的签名算法或MD2报文摘要算法)定义了
自己的实现。
获得实现实例的factory(工厂)方法
对于API中的每个引擎类,调用该引擎类中的factory方法就对某个特定的实现方法提出了请求并将之实
例化。factory方法是一种静态方法,它返回类的实例。
获取正确Signature(签名)对象的基本机制如下所示:用户通过指定签名算法名(如“带DSA的SHA1"),
或再加上提供所需实现的提供者名称,然后调用Signature类中的getlnstance方法,即可请求获得该对象。
getlnstance方法将找到一种满足给定算法和提供者参数的实现方法。如果不指定提供者,getlnstance将按
优先顺序搜索已注册的提供者,最后确定带指定算法的实现的提供者。有关注册提供者的详细信息,参见
Provider类。
核心类和接口
本节将讨论Java加密体系结构中提供的核心类和接口:
•Provider和Security类
,MessageDigest>Signature、KeyPairGenerator^KeyFactory>Algorithmparameters、
AlgorithmParameterGenerator>CertificateFactory>KeyStore和SecureRandom弓I擎类
•密钥接口和类
•算法参数规范接口和类及密钥规范接口和类
本节将演示每个类和接口中main方法的功能。相应的示例部分给出了这些类(MessageDigest、Signature>
KeyPairGenerator>SecureRandom>KeyFactory以及密钥规范类)的用法示例。
有关SecurityAPI包的完整参考文档,可在以下网址中找到:
•java.security包概览
•java.security.spec包概览
•erfaces包概览
Provider类
“密码服务提供者”(简称“提供者”)是指一个或一组包,该包可提供JDK安全API密码功能子集的具体
实现。Provider类是这个(或这组)包的接口。它含有访问提供者名称、版本号和其它信息的方法。
要实际提供密码服务的实现,某一实体(如某个开发小组)就必须编写实现代码和创建Provider类的子类。
该子类的构造函数将对JDK安全API查询由提供者所实现的服务所需各种属性的值进行设置。也就是说,
它指定了实现各种服务的类的名称。
提供者包可实现多种类型的服务一参见引擎类和算法。
不同的实现可能有不同的功能。有些可能是基于软件的,而另一些可能是基于硬件的。有些可能与平台无
关,而另一些可能是针对指定平台的。有些提供者提供源代码以供复查和评估用,而另一些却不提供。
Java加密体系结构(JCA)可让最终用户和开发人员都能决定各自所需。本节中,我们将说明最终用户如何
安装满足自身需求的密码实现,同时也介绍开发人员如何请求满足自身需求的实现。
(注意:有关实现Provider的信息,参见如何为Java加密体系结构实现Provider。)
如何请求和提供Provider的实现
对API中的每个引擎类,任一特定的实现都是通过下列方法来进行请求和实例化的:首先指定所要的算法
名称,有时再加上指定所需实现所属的提供者名称,然后调用该引擎类中的getlnstance方法。
如果不指定提供者,getlnstance将搜索已注册的提供者,确定与指定算法相关联的所需密码服务的实现。
在每个给定的Java虚拟机(JVM)中,将按某一给定的优先顺序来安装提供者。该顺序是在请求中未指定
提供者时搜索提供者所用的顺序。例如,假设JVM中安装有两个提供者,一个名为“PROVIDER」”,另一
个名为“PROVIDER2"。进一步假设:
•PROVIDER」实现SHAlwithDSA、SHA,MD5、DES和DES3
•PROVIDER_2实现SHAlwithDSA、MD5withRSA、MD2withRSA、MD2、MD5、RC4、RC5、DES和RSA
如果PROVIDER_1的优先顺序是1(最高优先顺序),而PROVIDER_2的优先顺序是2,则将导致以下行
为:
•假设正在查询MD5的实现。尽管这两个提供者都提供上述实现,但返回的是PROVIDER」上的实现,
这是因为PROVIDER_1具有最高优先权,因而将最先被搜索到。
•如果是在查询MD5withRSA签名算法,就会首先搜索PROVIDER_1以查询该方法。由于在
PROVIDER」上找不到该实现,因此接着对PROVIDER_2进行搜索。找到该实现后即将将其返回。
•假设是在查询SHAlwithRSA签名算法。由于所安装的提供者都不提供该实现,因此抛出
NoSuchAlgorithmException。
带提供者变量的getlnstance方法是为那些需要指定一个算法应由哪个提供者来提供的开发人员而准备的。
例如,联邦代理机构要用已被联邦认证的提供者的实现。不妨假设由PROVIDER」提供的的SHAlwithDSA
实现还没有接受这样的证书,而由PROVIDER_2提供的DSA实现已接受该证书。
于是,Federal程序将指定PROVIDER_2来进行下列调用,因为它含有已获证书的实现:
Signaturedsa=Signature.getlnstance("SHAlwithDSA","PROVIDER_2");
这种情况下,如果没有安装"PROVIDER_2”,则将抛出NoSuchProviderException,即使有另一个己安装了的
提供者可实现所请求的算法。
程序也可选择获取一个包括所有安装了的提供者的清单(使用Security类中的getProviders方法)并从该
清单中选取某个提供者)。
安装提供者
安装提供者包括两部分:安装提供者包中的类及对提供者进行配置。
安装Provider类
有几个方法可用于安装provider类:
•将包含这些类的zip或JAR文件放在CLASSPATH中的任何位置
•将提供者的JAR文件作为“已安装”或“已捆绑的”扩展来提供。有关如何部署某个扩展的详细信
息,参见如何发布扩展。
配置提供者
下一步是将提供者添加到认可的提供者的清单中。这是通过编辑JKDlib/security目录中的java.security文
件来静态完成的。因此,如果JDK安装在jdkl.2目录中,则该文件将是jdkl.2/lib/security/java.securityo
可在java.security中进行设置的一类属性具有以下形式:
vider。n=masterClassName
该语句声明了一个提供者,并指定其优先顺序n。优先顺序是在没有指定提供者时查询所请求的算法时搜
索各提供者所用的顺序。顺序以1为基础,即1是最高的优先级,紧接着是2等等。
masterClassName必须指定提供者的"main"类。提供者的文档将指定其主类。这个主类永远是Provider类
的一个子类。子类的构造函数设置了JDK密码API查询提供者所实现的算法或其它功能所需的各种属性的
值。
假设该主类是COM.vider.Acme,而且您想将Acme配置为具有第三优先级的提供者。为此,请将
下列行添加到java.security文件中:
vider.3=COM.vider.Acme
用户也可动态地注册提供者。要动态地注册提供者,请调用Security类中的addProvider或insertProviderAt
方法。这种类型的注册并不是持久的,且只能由“可信任”的程序来进行。参见安全。
Provider类的方法
每个Provider类的实例都有一个名称(目前区分大小写)、版本号和该提供者及其服务的描述字符串。通
过调用下述方法查询Provider实例,即可获得这些信息:
publicStringgetName()
publicdoublegetVersion()
publicStringgetlnfo()
Security类
Security类管理所安装的提供者和系统安全范围内的属性。它只含静态方法,并且无法实例化。
注意:用于添加或去除提供者及用于设置Security属性的方法只能由可信任的程序来执行。目前,“可信
任的程序”是指
•没在安全管理器下运行的本地应用程序,或者
•拥有执行指定方法权限的applet或应用程序(如下所示)。
为使代码可信任并可执行某项动作(如添加提供者),需要授予该applet对该特定动作的权限。
例如,在缺省Policy(策略)实现中,JDK安装的策略配置文件指定了给定代码源中代码的权限(即可访问
哪些类型的系统资源)。(有关详细信息,参见后面的内容和“缺省Policy实现和策略文件语法”及“Java
安全体系结构规范”文件)。
正在执行的代码总是来自某个特定的“代码源”。代码源不仅包括applet的源位置(URL),而且包括与签
写代码的私钥相对应的公钥的引用。代码源中的公钥由用户密钥仓库中的(符号)别名引用。
在策略配置文件中,代码源可表示为两个组件:一个是代码源(URL),另一个是别名(前面由“signedBy”
引导)。其中,别名用于标识含有校验代码签名所用公钥的keystore入口。
上述文件中的每个“grant”语句将一组权限授予指定的代码源,指明哪些动作是允许使用的。
以下所示的是一个样本策略配置文件.
grantsignedBy"sysadmin",CodeBase"file:/home/sysadmin/"{
permissionjava.security.SecurityPermission"Security.insertProvider.*";
permissionjava.security.SecurityPermission"Security.removeProvider.*";
permissionjava.security.SecurityPermission"Security.setProperty.*n;
);
该样本文件指定:只有从本地文件系统上“/home/sysadmin/”目录(及其以下目录)下某个已签名JAR文
件(其签名可用用户密钥仓库中的“sysadmin”别名所引用的公钥来校验)加载来的代码,才能调用Security
类中的方法以添加或去除提供者或设置Security属性。
代码源的任一组件(或两个组件)都可以没有。下面就是一个没有CodeBase组件的示例:
grantsignedBy"sysadmin"{
permissionjava.security.SecurityPermission"Security.insertProvider.*";
permissionjava.security.SecurityPermission"Security.removeProvider.*";
};
如果上述策略生效,则来自“sysadmin”签名JAR文件中的代码就可以添加/删除提供者一不管这个JAR
文件来源于何处。
以下是一个没有签名人的示例:
grantCodeBase"file:/home/sysadmin/"{
permissionjava.security.SecurityPermission"Security.insertProvider.*";
permissionjava.security.SecurityPermission"Security.removeProvider.*";
);
该例中,本地文件系统上“/home/sysadmin/”目录(及其以下目录)下的代码都可以添加/删除提供者。代
码无需签名。
以下是一个既无CodeBase又无signedBy的示例:
grant{
permissionjava.security.SecurityPermission"Security.insertProvider.*";
permissionjava.security.SecurityPermission"Security.removeProvider.*";
};
此处,由于代码源的两个组件都没有,因此任何代码(无论它来自何处或是否已签名,也不管是谁签名)
都可以添加/删除提供者。
管理Provider
Security类可用于查询所安装的提供者,也可用于运行时安装新提供者。
查询Provider
publicProvider[]getProviders()
该方法将返回一个数组,其中包含了所有已安装的提供者(从技术上来说,是每个包提供者的Prodiver子
类)。数组中各Provider的顺序就是它们的优先顺序。
publicProvidergetProvider(StringproviderName)
此方法将返回名为providerName的Provider。如果找不到该Provider,它将返回nulL
添加Provider
publicstaticintaddProvider(Providerprovider){
此方法将向已安装的提供者清单中添加提供者。它将返回该提供者所添加处的优先位置;如果由
于已安装该提供者的缘故而没有添加该提供者,则返回-1。
publicintinsertProviderAt(Providerprovider,intposition)
此方法将在某个指定位置添加新提供者。该位置就是在未指定要用哪个提供者的情况下,查询所
请求的算法时搜索各提供者所用的优先顺序。位置以1为基础,1的优先级最高,接着是2等
等。如果已将给定的提供者安装在所要求的位置上,则原先位于该位置的提供者及所有位置大于
该位置的提供者都要上移一个位置(向已安装的提供者的清单末端方向移动)。
注意,我们不能担保一定能将该提供者添加到所要求的位置上。例如,有时添加提供者是合法的,但只能
加到最后的位置。这种情况下position(位置)参数将被忽略。同样,如果该提供者已被安装,也就无法再
添加它了。
该方法将返回该提供者所添加处的实际优先位置;如果由于已安装该提供者的缘故而没有添加该提供者,
则返回-1。
注意:如果要改变某个提供者的优先级位置,必须先将它删除,然后再将它插入新的优先级位置。
删除提供者
publicvoidremoveProvider(Stringname)
此方法将删除指定名称的提供者。如果该提供者并未安装,它将无声返回。当指定的提供者被删除后,位
置大于被删除的提供者所在位置的所有提供者都要下移一个位置(向己安装的提供者清单起始方向移动)。
Security属性
Security类含有一系列全系统安全属性。可信任的程序可通过以下方法来访问这些属性并可对其进行设置。
publicstaticStringgetProperty(Stringkey)
publicstaticvoidsetProperty(Stringkey,Stringdatum)
MessageDigest类
MessageDigest类是一个引擎类,它是为了提供诸如SHA1或MD5等密码上安全的报文摘要功能而设计的。
密码上安全的报文摘要可接受任意大小的输入(一个字节数组),并产生固定大小的输出,该输出称为一个
摘要或散列。摘要具有以下属性:
•无法通过计算找到两个散列成相同值的报文。
•摘要不反映任何与输入有关的内容。
使用报文摘要可以生成数据唯一且可靠的标识符。有时它们被称为数据的“数字指纹”。
创建MessageDigest对象
计算摘要的第一步是创建报文摘要实例。象所有的引擎类一样,获取某类报文摘要算法的MessageDigest对
象的途径是调用MessageDigest类中的getlnstance静态factory方法:
publicstaticMessageDigestgetlnstance(Stringalgorithm)
注意:算法名不区分大小写。例如,以下所有调用都是相等的:
MessageDigest.getlnstance("SHA")
MessageDigest.getlnstance(nsha")
MessageDigest.getlnstance("sHa")
调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:
publicstaticMessageDigestgetlnstance(Stringalgorithm,Stringprovider)
调用getlnstance将返回已初始化过的报文摘要对象。因此,它不需要进一步的初始化。
更新报文摘要对象
计算数据的摘要的第二步是向已初始化的报文摘要对象提供数据。这将通过一次或多次调用以下某个
update(更新)方法来完成:
publicvoidupdate(byteinput)
publicvoidupdate(byte[]input)
publicvoidupdate(byte[]input,intoffset,intlen)
计算摘要
通过调用update方法提供数据后,程序就调用以下某个digest(摘要)方法来计算摘要:
publicbyte[]digest()
publicbyte[]digest(byte[]input)
publicintdigest(byte[]buf,intoffset,intlen)前两个方法返回计算出的摘要。后一个方法把计算出的摘要
储存在所提供的buf缓冲区中,起点是offset。len是buf中分配给该摘要的字节数。该方法返回实际存
储在buf中的字节数。
对接受输入字节数组变量的digest方法的调用等价于用指定的输入调用:
publicvoidupdate(byte[]input),接着调用不带参数的digest方法。
有关详细信息,参见示例部分。
Signature类
Signature类是个引擎类,它是为了提供诸如DSA或RSAwithMD5这样的数字签名算法功能而设计的。
密码学上安全的签名算法可接受任意大小的输入和一个私钥,并产生一个比较短(常常是固定大小的)的
名为signature的字节串,它具有以下属性:
•给定与签名的私钥相对应的公钥,就应能校验输入的真实性和完整性。
•签名和公钥不反映有关私钥的任何内容。
Signature对象可用于数据签名。它还可用于校验某个签名是否为与之关联的数据的真实签名。有关对数据
签名和校验的样例,参见示例部分。
Signature对象状态
Signature对象是个模型对象。这意味着Signature对象总是处在某个给定的状态(在这种状态下,它只能
进行一类操作)下。状态以各自的类(如Signature)中定义的final整数常数来表示。
Signature对象可能有三种状态:
•UNINITIALIZED
•SIGN
•VERIFY
Signature对象首次生成时将处于UNINITIALIZED(未初始化)态。Signature类定义了两个初始化方法:initSign
和initVerify方法,它们将分别把状态改为SIGN和VERIFY。
创建Signature对象
签名或校验签名的第一步是创建Signature实例。正如所有的引擎类一样,为特定类型的签名算法获取
Signature对象的途径是调用Signature类中的getlnstance静态factory方法:
publicstaticSignaturegetlnstance(Stringalgorithm)
注意:算法名称不区分大小写。
调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:?
publicstaticSignaturegetlnstance(Stringalgorithm,Stringprovider)
初始化Signature对象
使用Signature对象前必须先将它初始化。所用的初始化方法取决于该对象是先用于签名还是先用于校验。
如果是用于签名,必须用签名的拥有者实体的私钥来初始化该对象。这种初始化是通过调用以下方法来完
成的:
publicfinalvoidinitSign(PrivateKeyprivateKey)
该方法将Signature对象置于SIGN(签名)状态。
反之,如果Signature对象是用于校验,则必须先用签名的拥有者实体的公钥来初始化该对象。这种初始化
是通过调用以下方法来完成的:
publicfinalvoidinitVerify(PublicKeypublicKey)
该方法将Signature对象置于VERIFY(校验)状态。
签名
如果Signature对象已初始化为用于签名(即如果它处于SIGN状态),则可将待签数据提供给该对象。这
可通过一次或多次调用以下某个update方法来完成:
publicfinalvoidupdate(byteb)
publicfinalvoidupdate(byte[]data)
publicfinalvoidupdate(byte[]data,intoff,intlen)应该不断地调用update方法直到将所有待签的数据都
提供给该Signature对象。
要产生签名,只需调用以下某个sign(签名)方法:
publicfinalbyte[]sign()
publicfinalintsign(byte[]outbuf,intoffset,intlen)
第一个方法返回一个字节数组,内放签名结果。第二个方法将签名结果储存在所提供的outbuf缓冲区中,
起点是offset。len是outbuf中分派给签名的字节数。该方法返回实际存储的字节数。
签名被编码为两个整数r和s的标准ASN.1序列。有关如何在Java加密体系结构中使用ASN.1编码的
详细信息,参见附录B。
调用sign方法将把该signature对象重置为当初通过调用initSign方法对其进行初始化以用于签名时所处
的状态。也就是说,该对象将被重置并可通过重新调用update和sign(使用同一私钥)来产生另一个签
名。
也可以指定另一个私钥重新调用initSign或调用initVerify(将该Signature对象初始化为用于校验的对象)
校验
如果Signature对象被初始化为校验用(即如果它是处于VERIFY状态),则它可校验某个签名是否为与之
关联的数据的真实签名。要开始该过程,请将待校验的数据(与签名相对)提供给该对象。这可通过一次
或多次调用以下某个update方法来完成:
publicfinalvoidupdate(byteb)
publicfinalvoidupdate(byte[]data)
publicfinalvoidupdate(byte[]data,intoff,intlen)
应该不断调用update方法,直到将所有数据都提供给该Signature对象为止。
之后,可通过调用下面的verify(校验)方法来校验签名:
publicfinalbooleanverify(byte[]encodedSignature)
其中的参数必须是字节数组,该数组包含被编码为两个整数r和s的标准ANSI.1序列的签名。这是一种
常用的标准编码。它与由sign方法产生的一样。
verify方法返回一个布尔量,指明被编码的签名是否为提供给update方法的数据的真实签名。
调用Iverify方法将把该signature对象重置为当初通过调用initVerify方法对其进行初始化以用来校验时
所处的状态也就是说,该对象将被重置并可通过调用initVerify时其公钥被指定的身份来校验另一个签名。
也可以重新调用initVerify(将该Signature对象初始化为检验不同实体的签名)以指定不同的公钥,或者
调用initSign(将该Signature对象初始化为用于生成签名)。
算法参数类
算法参数规范接口和类
算法参数规范是对算法中所用参数组的“透明”表示。
一组参数的透明表示意思是可以通过相应规范类中定义的某个“get”(获取)方法来分别访问组中的每个参
数值(例如,DSAParameterSpec定义了getP、getQ和getG方法,分别用于访问p、q和g)«
这与不透明表示形成对照;正如Algorithmparameters类给出的那样,用户将无法直接访问各参数域,而只
能得到与该参数集相关联的算法名(通过getAlgorithm方法)和该参数集的某类编码(通过getEncoded方
法)。
在java.security.spec包中出现的算法参数规范接口和类将在下面进行说明。
AlgorithmParameterSpec接口
AlgorithmParameterSpec是密码参数透明规范的一个接口。
该接口不含任何方法或常数。它的唯一用途在于对所有的参数规范进行分组(以及为它们提供类型安全性)。
所有的参数规范都必须执行这一接口。
DSAParameterSpec类
该类(它实现AlgorithmParameterSpec接口)指定DSA算法中使用的参数组。它含有以下方法:
publicBigintegergetP()
publicBigintegergetQ()
publicBigintegergetG()
这些方法将返回以下的DSA算法参数:质数p、亚质数q和基数go
Algorithmparameters类
AlgorithmParameters类是个引擎类,它提供密码参数的不透明表示。
不透明表示的意思是:在这种表示中,不可以直接访问各参数域,只能得到与参数集相关联的算法名及该
参数集的某类编码。这与参数的透明表示形成对照,在透明表示中,用户可以通过相应规范类中定义的某
个"get"方法来分别访问每个值。注意:用户可以通过调用AlgorithmParameters的getParameterSpec方
法,将AlgorithmParameters对象转换成透明规范(参见下面的内容)。
创建AlgorithmParameters对象
正如所有的引擎类一样,为某一类型的算法获取AlgorithmParameters对象的途径是调用
AlgorithmParameters类中的getlnstance静态factory方法:
publicstaticAlgorithmParametersgetlnstance(Stringalgorithm)
注意:算法名称不区分大小写。
调用程序可选择指定提供者名称,以保证所要求的算法参数是由已命名提供者实现的:
publicstaticAlgorithmParametersgetlnstance(Stringalgorithm,Stringprovider)
初始化AlgorithmParameters对象
对某个AlgorithmParameters对象进行实例化后,必须用适当的参数规范或参数编码来调用init,以便对该
对象进行初始化:
publicvoidinit(AlgorithmParameterSpecparamSpec)
publicvoidinit(byte[]params)
publicvoidinit(byte[]params,Stringformat)
上面这些语句中,params(参数)是个数组,它包含了被编码的参数,format(格式)是编码格式名。在上
述带params变量但不带format变量的init方法中,将使用参数的主要解码格式。如果有参数的ASN.1
规范,主要解码格式就是ASN.lo
注意:AlgorithmParameters对象只能被初始化一次。也就是说,它们无法重用。
获取被编码的参数
Algorithmparameters对象中出现的参数的某个字节编码可通过调用getEncoded来获得:
publicbyte[]getEncoded()
该调用将以主要编码格式返回这些参数。如果存在这类参数的ANS.1规范,则主要编码格式就是ASN.lo
如果需要以指定的编码格式来返回这些参数,请使用
publicbyte[]getEncoded(Stringformat)
如果format是空的,则使用参数的主要编码格式,就象其它的getEncoded方法中那样。
请注意:在AlgorithmParameters的缺省实现(由"SUN”提供者提供)中,目前将忽略format变量。
将AlgorithmParameters对象转换为透明规范
算法参数的透明参数规范可以通过调用getParameterSpec从AlgorithmParameters对象中得到:
publicAlgorithmParameterSpecgetParameterSpec(ClassparamSpec)paramSpec
指示这些参数将在哪个规范类中返回。例如,它可以是DSAParameterSpec.class,表明这些参数应该是从
DSAParameterSpec类(该类在java.security.spec包中)的某个实例中返回的。
AlgorithmParameterGenerator类
AlgorithmParameterGenerator类是个引擎类,它用于产生一组与给定算法(当创建某个
AlgorithmParameterGenerator实例时,也就指定了算法)相匹配的参数。
创建AlgorithmParameterGenerator对象
正如所有的引擎类一样,为某一类型的算法获取AlgorithmParameterGenerator对象的途径是调用
AlgorithmParameterGenerator类中的getlnstance静态factory方法:
publicstaticAlgorithmParameterGeneratorgetlnstance(Stringalgorithm)
注意:算法名称不区分大小写。
调用程序可选择指定提供者的名称,以保证该算法的参数生成器是由已命名提供者实现的:
publicstaticAlgorithmParameterGeneratorgetlnstance(Stringalgorithm,Stringprovider)
初始化AlgorithmParameterGenerator对象
可用两种不同的方式来初始化AlgorithmParameterGenerator对象:与算法无关的方式及针对某个算法的方
式。
与算法无关的方式利用这样一个事实:所有的参数生成器均共用“大小”这个概念和随机源。大小量度是
由所有的算法参数普遍共用的,虽然不同的算法对它的解释并不一样。例如,在DSA算法参数中,“大小”
对应于质数模数的大小,单位是比特(有关特定算法的大小的信息,参见附录B:算法)。使用这种方法时,
针对算法的参数的产生值(如果有)将缺省为一些标准值。init方法接受这两类普遍共用的变量:
publicvoidinit(intsize,SecureRandomrandom);
还有一个方法只接受size(大小)变量;它使用由系统提供的随机源:
publicvoidinit(intsize)
另一个处理方式是使用针对算法的语句来初始化参数生成器,这些语句表示为一组由
AlgorithmParameterSpec对象给出的针对算法的参数生成值:
publicvoidinit(AlgorithmParameterSpecgenParamSpeczSecureRandomrandom)
publicvoidinit(AlgorithmParameterSpecgenParamSpec)
例如,要生成Diffie-Hellman系统参数,参数生成值通常由质数模数的大小和随机指数的大小组成,两者都
以比特数给出。Diffie-Hellman算法将作为JCE1.2的组件发布。
生成算法参数
一旦创建并初始化某个AlgorithmParameterGenerator对象后,就可以用generateParameters方法来生成算
法参数:
publicAlgorithmparametersgenerateParameters()
密钥接口
密钥接口是所有不透明密钥的最高级接口。它定义了所有不透明密钥对象所共享的功能。
不透明密钥表示的意思是:在这种表示中,用户无法直接访问组成密钥的密钥信息。另言之:“不透明”
限制了对密钥的访问一只能用"Key"接口中定义的三种方法(见下面)来访问:getAlgorithm、getFormat
和getEncodedo这与透明表示形成对照。在透明表示中,用户可以通过相应规范类中定义的某个“get”
方法来分别访问每个密钥资料值。
所有不透明密钥都有三个属性:
•算法
这是该密钥的密钥算法。该密钥算法通常是一种加密算法或不对称加密算法(例如DSA或RSA),它
将与上述算法及有关的算法(如MD5withRSA、SHA1withRSA等)协同工作。密钥算法的名称可由
下面方法来获得:
publicStringgetAlgorithm()
•编码方式
这是需要在Java虚拟机外提供密钥的标准表示时,所使用的一种密钥外部编码方式。它按某种标准
格式(如X.509或PKCS#8)对密钥进行编码,并用以下方法返回:
publicbyte[]getEncoded()
•格式
这是经过编码处理后的密钥的格式名。它由以下方法返回:
publicStringgetFormat()
密钥一般通过密钥生成器、证书和密钥规范(用KeyFactory方法)获得,或通过KeyStore的实现
访问管理密钥的“密钥仓库”数据库来获得。
可以用与算法有关的方式,用KeyFactory解析经过编码处理的密钥。
也可以用CertificateFactory来解析证书。
PublicKey和PrivateKey接口
PublicKey和PrivateKey接口(两者都是对Key接口的扩展)都是不含方法的接口,用在类型安全和类型
识别中。
密钥规范接口和类
密钥规范是组成密钥的密钥信息的透明表示。如果密钥存储在某个硬件设备上,它的规范中就可能含有可
帮助识别该设备上的密钥的信息。
密钥的透明表示意味着可以通过相应规范类中定义的某个“get”方法来分别访问每个密钥信息的值。例如,
DSAPrivateKeySpec定义了getX、getP、getQ和getG方法,用以访问私钥x和计
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026及未来5年干红瓶项目可行性研究报告(市场调查与数据分析)
- 密云中考数学试题及答案
- 2026年自媒体营销报告:行业现状与市场拓展策略
- 2026年行业进出口报关行业报告
- 2026年礼品行业市场细分研究报告:礼品市场品牌影响力分析001
- 2026年行业远程会议市场容量报告:协同办公市场潜力分析
- 2026年新材料行业渠道拓展与库存管理报告
- 2026年超净技术市场创新应用报告
- 2026年共享经济行业宏观经济影响与市场潜力分析报告
- 2026年镭矿行业创新技术报告
- 2026年中石化笔试题库(含答案)
- 2026年厨师人员考试模拟试卷(含答案)
- 小学美术四年级社团课教学设计《孵蛋的大白鹅》综合材料创作实践
- 高中美术必修《中国书法和中国画的密切关系》教学设计
- 工程决算编制办法说明
- 2026秋苏教版八年级上册生物全册每课知识点清单
- 2026秋沪科版(五四学制)八年级物理上册全册每课知识点清单
- 2026中银数字服务(南宁)有限公司招聘笔试模拟试题及答案详解
- RoHS 3.0 指令 2024-1020-EU 中文版(完整译文 + 新旧对比 + 2027 年实施时间表)
- 20S515 钢筋混凝土及砖砌排水检查井
- 企业员工预防职务犯罪课件
评论
0/150
提交评论