数字签名算法
RSA、DSA和ECDSA三种算法。
通常是先对消息做摘要处理,然后使用私钥对摘要值进行签名处理;验证时,使用公钥验证消息的摘要值。
public class RSASin
{
private static final String KEY_ALGORITHM= "RSA";
public static final String SIGNATURE_ALGORITHM= "MD5WithRSA";
private static final String PUBLIC_KEY= "RSAPublicKey";
private static final String PRIVATE_KEY= "RSAPrivateKey";
private static final int KEY_SIZE=512;
private static byte[] pubKey;
private static byte[] priKey;
//数字签名,根据私钥获取数字签名
public static byte[]
sign(byte[] data, byte[]
privateKey) throws Exception{
//私钥规范
PKCS8EncodedKeySpec pkcs8= new PKCS8EncodedKeySpec(privateKey);
//密钥工厂
KeyFactory keyFac=KeyFactory. getInstance(KEY_ALGORITHM);
PrivateKey priKey=keyFac.generatePrivate(pkcs8);
//实例化Signature
Signature signature=Signature. getInstance(SIGNATURE_ALGORITHM);
//初始化
signature.initSign(priKey);
//更新
signature.update(data); //根据数据更新签名
//签名
return signature.sign();
}
//校验--公钥验证
public static boolean verify(byte[]
data, byte[] publicKey,byte[]
sign) throws Exception{
//公钥规范
X509EncodedKeySpec x509= new X509EncodedKeySpec(publicKey);
KeyFactory keyFac=KeyFactory. getInstance(KEY_ALGORITHM);
//生成公钥
PublicKey pubKey=keyFac.generatePublic(x509);
Signature signature=Signature. getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
//验证
return signature.verify(sign);
}
//取得私钥
public static byte[]
getPrivateKey(Map<String,Object> keyMap){
Key key=(Key) keyMap.get( PRIVATE_KEY);
return key.getEncoded();
}
//公钥
public static byte[]
getPublicKey(Map<String,Object> keyMap){
Key key=(Key)keyMap.get( PUBLIC_KEY);
return key.getEncoded();
}
//初始化密钥对
public static Map<String,Object>
initKey() throws Exception{
KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance( KEY_ALGORITHM);
keyPairGen.initialize( KEY_SIZE);
//生成密钥对
KeyPair keyP=keyPairGen.generateKeyPair();
//公钥
RSAPublicKey publicKey=(RSAPublicKey)keyP.getPublic();
//私钥
RSAPrivateKey privateKey=(RSAPrivateKey)keyP.getPrivate();
//封装密钥
Map<String,Object> keyMap= new HashMap<String,Object>(2);
keyMap.put( PRIVATE_KEY,
(Object) privateKey);
keyMap.put( PUBLIC_KEY,
(Object) publicKey);
return keyMap;
}
public static final void main(String[]
args) throws Exception{
Map<String,Object> kMap= initKey();
pubKey=getPublicKey(kMap);
priKey=getPrivateKey(kMap);
System. err.println("公钥:\n" +Base64.encodeBase64String (pubKey ));
System. err.println("私钥:\n" +Base64.encodeBase64String (priKey ));
String str= "RSA数字签名" ;
byte[]
data=str.getBytes();
//产生签名
byte[]
sign=sign(data, priKey);
System. err.println("签名:\n" +Hex.encodeHexString (sign));
//验证签名
boolean status=verify(data, pubKey,
sign);
System. err.println("状态:\n" +status);
//验证
assertTrue(status);
}
}