数字签名的基础是公钥和私钥的非对称加密,发送者使用私钥加密消息摘要(签名),接收者使用公钥解密消息摘要以验证签名是否是某个人的。
基本步骤:
得到keyPairGenerator的实例对象,并调用其generateKeyPair()方法创建KeyPair对象。
调用KeyPair对象的getPrivate和getPublic方法,分别得到PrivateKey对象和PublicKey对象。
得到Signature的实例对象,调用其initSign()方法和指定PrivateKey对象,然后调用update方法和sign方法产生签名
调用Signature对象的initVerify()方法和指定PublicKey对象,然后调用update方法和verify()方法对原始数据的签名进行验证。
例子:
package com.study.security;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
/**
* 数字签名
* 私钥签名公钥校验
* @author Administrator
*
*/
public class DigitSign {
public static void main(String[] args) throws Exception{
sign();
verify();
}
//签名
private static void sign()throws Exception{
KeyPairGenerator generator=KeyPairGenerator.getInstance("RSA");
KeyPair keyPair=generator.generateKeyPair();
PublicKey publicKey=keyPair.getPublic();
PrivateKey privateKey=keyPair.getPrivate();
Signature signature=Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update("hello java!".getBytes("UTF-8"));
byte[] signedResult=signature.sign();
//保存数据与公钥
saveKey(publicKey, "sign_public.key");
saveData(signedResult, "sign_data.data");
}
//校验
private static void verify()throws Exception{
byte[] data=readData("sign_data.data");
PublicKey publicKey=(PublicKey)readKey("sign_public.key");
Signature signature=Signature.getInstance("MD5withRSA");
signature.initVerify(publicKey);
signature.update("hello java!".getBytes("UTF-8"));
boolean isYourSign=signature.verify(data);
System.out.println("校验的结果:"+isYourSign);
}
//保存数据的方法
public static void saveData(byte[] results,String dataName)throws Exception{
FileOutputStream fosData=new FileOutputStream(dataName);
fosData.write(results);
fosData.close();
}
//恢复数据的方法
public static byte[] readData(String dataName)throws Exception{
FileInputStream fisDat= new FileInputStream(dataName);
//读二进制数据
ByteArrayOutputStream arrayOutputStream=new ByteArrayOutputStream();
int len=0;
byte[] data=new byte[1024];
while((len=fisDat.read(data))!=-1){
arrayOutputStream.write(data, 0, len);
}
byte[] result=arrayOutputStream.toByteArray();
arrayOutputStream.close();
fisDat.close();
return result;
}
//保存密钥的方法
public static void saveKey(Key key,String keyName) throws Exception{
FileOutputStream foskey=new FileOutputStream(keyName);
ObjectOutputStream oos=new ObjectOutputStream(foskey);
oos.writeObject(key);
oos.close();
foskey.close();
}
//恢复密钥的方法
public static Key readKey(String keyName) throws Exception{
FileInputStream fiskey=new FileInputStream(keyName);
ObjectInputStream oiskey=new ObjectInputStream(fiskey);
Key key=(Key)oiskey.readObject();
oiskey.close();
fiskey.close();
return key;
}
}