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,则认为验证成功。上述代码稍加改动就可用于数字证书的签名和认证操作。