数字签名技术 -- DSA算法

    xiaoxiao2021-04-16  39

    DSA算法是1991年美国国家标准技术协会公布的数字签名标准(DSS)的核心算法。本质上是ElGamal数字签名算法,仅能与SHA系列算法结合,没有相应的MD融合算法。

    DSA算法和RSA算法的异同

    DSA算法是DSS技术的核心算法,与RSA算法的异同如下:

    二者都是数字签名算法中的重要组成,缺一不可;DSA算法仅仅包含数字签名算法,没有密钥信息;DSA算法产生的数字证书无法进行加密通信,HTTPS不会使用这个算法;RSA算法包含加解密的密钥信息,同时又数字签名算法的作用;

    算法家族

    包含:SHA1withDSA、SHA224withDSA、SHA256withDSA、SHA384withDSA、SHA512withDSA五种算法。

    密钥长度都是512-1024位。

    Java中的算法实现

    JDK 6实现了DSA算法,仅仅实现了SHA1withDSA算法。

    示例代码,代码和RSA数字签名算法的一样,只不过是算法名字变了下,可见Java的API设计还是很不错的。

    public class SignatureTest { //唯一不一样的是这里 public static final String SIGN_ALGORITHM = "SHA1withDSA"; private static final String KEY_ALGORITHM = "RSA"; private static final int KEY_SIZE = 1024; public static void main(String[] args) throws Exception { KeyPair keyPair = initKey(); String input = "Sign Me"; byte[] sign = sign(input.getBytes(), keyPair.getPrivate().getEncoded()); boolean verify = verify(input.getBytes(), sign, keyPair.getPublic().getEncoded()); String msg = String.format("原始数据: %s , Sign : %s , Verify : %s", input, toBase64(sign), verify); System.out.println(msg); // 从二进制位角度看,sign的长度和密钥长度一致 System.out.println("Sign Size : " + (sign.length * 8) + " Key Size : " + KEY_SIZE); } public static KeyPair initKey() throws Exception { KeyPairGenerator keyPairGr = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGr.initialize(KEY_SIZE); KeyPair keyPair = keyPairGr.generateKeyPair(); return keyPair; } public static byte[] sign(byte[] data, byte[] privateKey) throws Exception { // 将byte[]的key格式化回来 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 获取算法实例并初始化 Signature signature = Signature.getInstance(SIGN_ALGORITHM); signature.initSign(priKey); signature.update(data); byte[] sign = signature.sign(); return sign; } public static boolean verify(byte[] data, byte[] sign, byte[] publicKey) throws Exception { // 获取算法实例并初始化 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); Signature signature = Signature.getInstance(SIGN_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 验证数据和签名是否一致,放否认,放篡改 boolean verify = signature.verify(sign); return verify; } public static String toBase64(byte[] data) { return new String(Base64.getEncoder().encode(data)); } }
    转载请注明原文地址: https://ju.6miu.com/read-672468.html

    最新回复(0)