DSA签名算法
DSA就是Digital Signature Algorithm,他使用的是EIGamal数字签名算法
DSA只能配合SHA使用:
1. 所以有SHA1withDSA
2. SHA256withDSA
3. SHA512withDSA
和RSA数字签名相比,DSA的签名算法更快
package com.learn.securl;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* 用DSA签名的时候和RSA是完全一样的
* 可以看到使用DSA和RSA签名是非常类似的
* 用公钥签名的结果为true
* 修改原始签名的结果为false
* @author Leon.Sun
*
*/
public class SecDSASignature {
PrivateKey sk;
PublicKey pk;
/**
* 生成公钥/私钥对
* @throws GeneralSecurityException
*/
public SecDSASignature() throws GeneralSecurityException{
/**
* 只是算法名称从RSA变成了DSA
*/
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DSA");
kpGen.initialize(1024);
KeyPair kp = kpGen.generateKeyPair();
this.sk = kp.getPrivate();
this.pk = kp.getPublic();
}
/**
* 从以保存的字节中(例如:读取文件)恢复公钥/私钥
* @param pk
* @param sk
* @throws GeneralSecurityException
*/
public SecDSASignature(byte[] pk, byte[] sk) throws GeneralSecurityException{
KeyFactory kf = KeyFactory.getInstance("DSA");
X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pk);
this.pk = kf.generatePublic(pkSpec);
PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(sk);
this.sk = kf.generatePrivate(skSpec);
}
/**
* 把私钥导出为字节
* @return
*/
public byte[] getProvateKey(){
return this.sk.getEncoded();
}
/**
* 把公钥导出为字节
* @return
*/
public byte[] getPublicKey(){
return this.pk.getEncoded();
}
/**
* sign by sk
* @param message
* @return
* @throws GeneralSecurityException
*/
public byte[] sign(byte[] message) throws GeneralSecurityException{
Signature signature = Signature.getInstance("SHA1withDSA");
signature.initSign(this.sk);
signature.update(message);
return signature.sign();
}
/**
* sign by pk
* @param message
* @param sign
* @return
* @throws GeneralSecurityException
*/
public boolean verify(byte[] message, byte[] sign) throws GeneralSecurityException{
Signature signature = Signature.getInstance("SHA1withDSA");
signature.initVerify(this.pk);
signature.update(message);
return signature.verify(sign);
}
public static void main(String[] args) throws Exception{
byte[] message = "Hello, 使用SHA1withDSA算法进行数字签名!".getBytes();
SecDSASignature rsas = new SecDSASignature();
byte[] sign = rsas.sign(message);
System.out.println("sign: " + Base64.getEncoder().encodeToString(sign));
boolean verified = rsas.verify(message, sign);
System.out.println("verify: " + verified);
// 用另一个公钥验证:
boolean verified2 = new SecDSASignature().verify(message, sign);
System.out.println("verify with another public key: " + verified2);
// 修改原始信息:
message[0] = 100;
boolean verified3 = rsas.verify(message, sign);
System.out.println("verify changed message: " + verified3);
}
}
最后我们总结一下:
1. DSA是另一种数字签名算法
2. 还有另一种数字签名算法,例如ECDSA:Elliptic Curve Digital Signature Algorithm(Bouncy Castle)