本文共 4588 字,大约阅读时间需要 15 分钟。
DSA(Digital Signature Algorithm)是Schnorr和ElGamal签名算法的变种,被美国NIST作为数字签名标准(DigitalSignature Standard)。
DSA(Digital Signature Algorithm,数字签名算法,用作数字签名标准的一部分),它是另一种公开密钥算法,它不能用作加密,只用作数字签名。DSA使用公开密钥,为接受者验证数据的完整性和数据发送者的身份。它也可用于由第三方去确定签名和所签数据的真实性。DSA算法的安全性基于解离散对数的困难性,这类签字标准具有较大的兼容性和适用性,成为网络安全体系的基本构件之一。
DSA只能与SHA-1一起使用。
package lzf.cipher.jdk;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;/** * @author java小工匠 */public class JdkSignatureDsaUtils { public static final String DSA = "DSA"; public static final String MD5withDSA = "SHAwithDSA"; // 初始化密钥对 public static KeyPair initKey() { try { KeyPairGenerator generator = KeyPairGenerator.getInstance(DSA); // 512 -65536 && 64 的倍数 generator.initialize(1024); return generator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } // 获取公钥 public static byte[] getPublicKey(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return bytes; } // 获取公钥 public static String getPublicKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return encodeHex(bytes); } // 获取私钥 public static byte[] getPrivateKey(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return bytes; } // 获取私钥 public static String getPrivateKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return encodeHex(bytes); } // 签名 public static byte[] sign(byte[] data, byte[] privateKey, String type) { try { // 还原使用 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory keyFactory = KeyFactory.getInstance(DSA); PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 1、实例化Signature Signature signature = Signature.getInstance(type); // 2、初始化Signature signature.initSign(priKey); // 3、更新数据 signature.update(data); // 4、签名 return signature.sign(); } catch (Exception e) { throw new RuntimeException(e); } } // 验证 public static boolean verify(byte[] data, byte[] publicKey, byte[] sign, String type) { try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory keyFactory = KeyFactory.getInstance(DSA); PublicKey pubKey = keyFactory.generatePublic(keySpec); // 1、实例化Signature Signature signature = Signature.getInstance(type); // 2、初始化Signature signature.initVerify(pubKey); // 3、更新数据 signature.update(data); // 4、签名 return signature.verify(sign); } catch (Exception e) { throw new RuntimeException(e); } } // 数据准16进制编码 public static String encodeHex(final byte[] data) { return encodeHex(data, true); } // 数据转16进制编码 public static String encodeHex(final byte[] data, final boolean toLowerCase) { final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER; final int l = data.length; final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return new String(out); } public static void main(String[] args) { String str = "java小工匠"; byte[] data = str.getBytes(); // 初始化密钥度 KeyPair keyPair = initKey(); byte[] publicKey = getPublicKey(keyPair); byte[] privateKey = getPrivateKey(keyPair); // 签名 String type = MD5withDSA; byte[] sign = sign(str.getBytes(), privateKey, type); // 验证 boolean b = verify(data, publicKey, sign, type); System.out.println("验证:" + b); }}
转载地址:http://vmqpo.baihongyu.com/