JAVA加密解密之DSA(Digital Signature Algorithm)算法

x33g5p2x  于2021-12-25 转载在 Go  
字(5.1k)|赞(0)|评价(0)|浏览(378)

DSA算法简介

DSA-Digital Signature Algorithm是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

DSA算法实现

package com.jianggujin.codec;

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 com.jianggujin.codec.util.JCodecException;

/** * DSA-Digital Signature Algorithm * 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature * Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。 * 如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级! * * @author jianggujin * */
public class JDSA {
   public static final String ALGORITHM = "DSA";

   /** * DSA签名算法 * * @author jianggujin * */
   public static enum JDSASignatureAlgorithm {
      SHA1withDSA, SHA224withDSA, SHA256withDSA;
      public String getName() {
         return this.name();
      }
   }

   /** * 初始化密钥 * * @return */
   public static KeyPair initKey() {
      return initKey(1024);
   }

   /** * 初始化密钥 * * @param keySize * @return */
   public static KeyPair initKey(int keySize) {
      try {
         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
         keyPairGen.initialize(keySize);
         return keyPairGen.generateKeyPair();
      } catch (Exception e) {
         throw new JCodecException(e);
      }
   }

   /** * 签名 * * @param data * @param privateKey * @param signatureAlgorithm * @return */
   public static byte[] sign(byte[] data, byte[] privateKey, String signatureAlgorithm) {
      try {
         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);

         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

         Signature signature = Signature.getInstance(signatureAlgorithm);
         signature.initSign(priKey);
         signature.update(data);
         return signature.sign();
      } catch (Exception e) {
         throw new JCodecException(e);
      }
   }

   /** * 验签 * * @param data * @param publicKey * @param sign * @param signatureAlgorithm * @return */
   public static boolean verify(byte[] data, byte[] publicKey, byte[] sign, String signatureAlgorithm) {
      try {
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);

         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

         PublicKey pubKey = keyFactory.generatePublic(keySpec);

         Signature signature = Signature.getInstance(signatureAlgorithm);
         signature.initVerify(pubKey);
         signature.update(data);

         return signature.verify(sign);
      } catch (Exception e) {
         throw new JCodecException(e);
      }
   }

}

测试代码:

package com.jianggujin.codec.test;

import java.io.File;
import java.security.KeyPair;

import org.junit.Test;

import com.jianggujin.codec.JBase64;
import com.jianggujin.codec.JBase64.JEncoder;
import com.jianggujin.codec.JDSA;
import com.jianggujin.codec.JDSA.JDSASignatureAlgorithm;

public class DSATest {
   String str = "jianggujin";
   File file = new File(getClass().getSimpleName() + ".dat");

   @Test
   public void test() throws Exception {
      System.out.println("原串:" + str);
      JEncoder encoder = JBase64.getEncoder();
      KeyPair keyPair = JDSA.initKey();

      byte[] keyPairPrivate = keyPair.getPrivate().getEncoded();
      byte[] keyPairPublic = keyPair.getPublic().getEncoded();
      System.out.println("私钥:" + encoder.encodeToString(keyPairPrivate, "UTF-8"));
      System.out.println("公钥:" + encoder.encodeToString(keyPairPublic, "UTF-8"));
      for (JDSASignatureAlgorithm algorithm : JDSASignatureAlgorithm.values()) {
         System.out.println("-----------------------------------------");
         System.out.println("签名算法:" + algorithm.getName());
         byte[] signed = JDSA.sign(str.getBytes(), keyPairPrivate, algorithm.getName());
         System.out.println("签名:" + encoder.encodeToString(signed, "UTF-8"));

         boolean verify = JDSA.verify(str.getBytes(), keyPairPublic, signed, algorithm.getName());
         System.out.println("验签:" + verify);
      }
   }
}

测试结果:
原串:jianggujin
私钥:MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUeCsXTr9h606CofNraKffXd3nHi8=
公钥:MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAVR7OIh6cezSQ282OrAX0MKPg+/WAoU/EJolDkvwQe8reR+8NLgIWY9PcEXimjnSoDJJq+ajaLtNCdlPO6/pqzDoA1QnmMxw70lOKDhYdjLuIUXrk6JsucI45fa8b8AD5pym0Ou+NdmanHKvd8cBpeCbVUkRoS/q0AO6i99xyZoE=
—————————————–
签名算法:SHA1withDSA
签名:MC0CFQCRPEpZoudVU+dpWNzMW9Y4ncW0GQIUQDlnzgSyGxMNbYzGRgMv+Rknn5Y=
验签:true
—————————————–
签名算法:SHA224withDSA
签名:MCwCFCmSv84K1uhZoSJP4rNTHN4Xa3dfAhQX5KrtkfaW2zo+fN6QdNALfaD2Og==
验签:true
—————————————–
签名算法:SHA256withDSA
签名:MCwCFHJS9SE5rTOsvBmxxn6ESSJ5OIlSAhQsTNk1XeSoucD2avzNKN8vSNAJqg==
验签:true

相关文章