3.2.13 Signature

Signature类用来生成和验证数字签名,它同样是一个引擎类。


//提供一个引擎,用以创建和验证数字签名。

public abstract class Signature

extends SignatureSpi


❑方法详述

使用Signature对象签名数据或验证签名包括以下三个阶段:

1)初始化

·初始化验证签名的公钥

·初始化签署签名的私钥

2)更新

·根据初始化类型,可更新要签名或验证的字节。

3)签署或验证所有更新字节的签名。

按照以上描述,我们先通过getInstance()工厂方法完成实例化对象。

一种简单的方式就是指定算法名称,直接获得Signature对象,方法如下所示:


//返回实现指定签名算法的Signature对象。

public static Signature getInstance(String algorithm)


另一种方式就是指定算法名称的同时指定该算法的提供者,方法如下所示:


//返回实现指定签名算法的Signature对象。

public static Signature getInstance(String algorithm, Provider provider)

//返回实现指定签名算法的Signature对象。

public static Signature getInstance(String algorithm, String provider)


在以下几步操作中,我们会看到消息摘要处理的一些类似的方法,大家可以参见3.2.3节和3.3.1节的内容。

目前,Signature支持NONEwithDSA和SHA1withDSA两种基于DSA算法的签名算法,同时还支持MD2withRSA、MD5withRSA、SHA1withRSA、SHA256withRSA、SHA384withRSA和SHA512withRSA六种基于RSA算法的签名算法。

关于Java 6版本中提供的算法信息,请参见本书附录。

完成实例化对象后,我们要初始化Signature对象:


//初始化这个用于签名的Signature对象。

public final void initSign(PrivateKey privateKey)

//初始化这个用于签名的Signature对象。

public final void initSign(PrivateKey privateKey, SecureRandom random)


上述两种方法是用于签名操作的初始化,如果用于验证操作则需要通过以下方法:


//初始化此用于验证的Signature对象。

public final void initVerify(PublicKey publicKey)

//使用来自给定证书的公钥初始化用于验证的Signature对象。

public final void initVerify(Certificate certificate)


注意上述方法的参数有所不同,前一种方法用于一般数字签名的验证操作,后一种方法则用于数字证书的验证操作。

完成初始化操作后,我们就可以通过以下方法更新Signature对象中的数据了。

Signature类的update()方法定义与MessageDigest类的update()方法相类似,可以通过更新一个字节,也可以更新一个字节数组,方法如下所示:


//更新要由字节签名或验证的数据。

public final void update(byte b)

//使用指定的字节数组更新要签名或验证的数据。

public final void update(byte[]data)


另一种方式就是根据偏离量做更新处理,方法如下所示:


//从指定的偏移量开始,使用指定的byte数组更新要签名或验证的数据。

public final void update(byte[]data, int off, int len)


或者使用缓冲方式,方法如下所示:


//使用指定的ByteBuffer更新要签名或验证的数据。

public final void update(ByteBuffer data)


在完成更新操作后,我们就可以做签名操作了:


//返回所有已更新数据的签名字节。

public final byte[]sign()

//完成签名操作,并得到存储在缓冲区中的签名字节长度。

public final int sign(byte[]outbuf, int offset, int len)


终于到了验证操作这一步,可通过以下方法完成:


//验证传入的签名,并返回验证结果。

public final boolean verify(byte[]signature)

//从指定的偏移量开始,验证指定的字节数组中传入的签名,并返回验证结果。

public final boolean verify(byte[]signature, int offset, int length)


此外,Signature提供了以下两种方法来设置和获取算法参数:


//使用指定的参数集初始化此签名引擎。

public final void setParameter(AlgorithmParameterSpec params)

//返回与此签名对象一起使用的参数。

public final AlgorithmParameters getParameters()


Signature类作为引擎类,同样提供如下两个常用方法:


//返回此签名对象的算法名称。

public final String getAlgorithm()

//返回此签名对象的提供者。

public final Provider getProvider()


Signature类覆盖了SignatureSpi类,方法如下所示:


//如果此实现可以复制,则返回副本。

public Object clone()

/返回此签名对象的字符串表示形式,以提供包括对象状态和所用算法名称在内的信息。/

public String toString()


❑实现示例

代码清单3-11展示了如何使用私钥完成数字签名的操作。

代码清单3-11 数字签名处理


//待做数字签名的原始信息。

byte[]data="Data Signature".getBytes();

//实例化KeyPairGenerator对象,并指定DSA算法。

KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("DSA");

//初始化KeyPairGenerator对象。

keyPairGen.initialize(1024);

//生成KeyPair对象。

KeyPair keyPair=keyPairGen.generateKeyPair();

//实例化Signature对象。

Signature signature=Signature.getInstance(keyPairGen.getAlgorithm());

//初始化用于签名操作的Signature对象。

signature.initSign(keyPair.getPrivate());

//更新

signature.update(data);

//获得签名,即字节数组sign。

byte[]sign=signature.sign();


私钥完成签名,公钥则用于完成验证,方法如下所示:


//初始化用于验证操作的Signature对象。

signature.initVerify(keyPair.getPublic());

//更新

signature.update(data);

//获得验证结果

boolean status=signature.verify(sign);


在上述示例代码中,如果变量status值为true,则认为验证成功。上述代码稍加改动就可用于数字证书的签名和认证操作。