DSA签名算法 - Java加密与安全

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)

猜你喜欢

转载自blog.csdn.net/Leon_Jinhai_Sun/article/details/89944976