zoukankan      html  css  js  c++  java
  • java-信息安全(十)-数字签名算法DSA

    概述

    信息安全基本概念:

    • DSA算法(Digital Signature Algorithm,数据签名算法)

    DSA

      Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSfS(DigitalSignature Standard)。

      简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

    算法分类

    算法 密钥长度 默认长度 签名长度 实现的方
    SHA1withDSA 512-65536
    (64的整数倍)
    1024 同密钥 JDK
    SHA224withDSA 同上 1024 同密钥 BC
    SHA256withDSA ... 1024 同密钥 BC
    SHA384withDSA ... 1024 同密钥 BC
    SHA512withDSA ... 1024 同密钥 BC

    签名示例

    复制代码
    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.sun.org.apache.xerces.internal.impl.dv.util.HexBin;  
      
    import sun.security.provider.DSAPrivateKey;  
    import sun.security.provider.DSAPublicKey;  
      
    public class DSA {  
        private static String src = "dsa security";  
        public static void main(String[] args) {  
            jdkDSA();  
        }  
          
        public static void jdkDSA(){  
            try {  
                //1.初始化密钥   
                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");  
                keyPairGenerator.initialize(512);  
                KeyPair keyPair = keyPairGenerator.generateKeyPair();  
                DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();  
                DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate();  
                  
                  
                //2.执行签名  
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());  
                KeyFactory keyFactory = KeyFactory.getInstance("DSA");  
                PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);  
                Signature signature = Signature.getInstance("SHA1withDSA");  
                signature.initSign(privateKey);  
                signature.update(src.getBytes());  
                byte[] res = signature.sign();  
                System.out.println("签名:"+HexBin.encode(res));  
                  
                //3.验证签名  
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());  
                keyFactory = KeyFactory.getInstance("DSA");  
                PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);  
                signature = Signature.getInstance("SHA1withDSA");  
                signature.initVerify(publicKey);  
                signature.update(src.getBytes());  
                boolean bool = signature.verify(res);  
                System.out.println("验证:"+bool);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
              
        }  
    }  
    复制代码

    示例代码

    复制代码
    package com.jd.order.util.encryption;
    
    import java.security.Key;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.SecureRandom;
    import java.security.Signature;
    import java.security.interfaces.DSAPrivateKey;
    import java.security.interfaces.DSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.commons.codec.binary.Base64;
    
    /**
     * DSA数字签名组件
     * 
     * @author 木子旭
     * @since 2017年3月17日上午10:37:30
     * @version %I%,%G%
     */
    public class DSACoder {
        public static final String ALGORITHM = "DSA";
    
        /**
         * 默认密钥字节数
         * 
         * <pre>
         * DSA  
         * Default Keysize 1024   
         * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
         * </pre>
         */
        private static final int KEY_SIZE = 1024;
    
        /**
         * 默认种子
         */
        private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";
    
        private static final String PUBLIC_KEY = "DSAPublicKey";
        private static final String PRIVATE_KEY = "DSAPrivateKey";
    
        /**
         * 用私钥对信息生成数字签名
         * 
         * @param data
         *            加密数据
         * @param privateKey
         *            私钥
         * 
         * @return
         * @throws Exception
         */
        public static String sign(byte[] data, String privateKey) throws Exception {
            // 解密由base64编码的私钥
            byte[] keyBytes = decryptBASE64(privateKey);
    
            // 构造PKCS8EncodedKeySpec对象
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    
            // KEY_ALGORITHM 指定的加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    
            // 取私钥匙对象
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    
            // 用私钥对信息生成数字签名
            Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
            signature.initSign(priKey);
            signature.update(data);
    
            return encryptBASE64(signature.sign());
        }
    
        /**
         * 校验数字签名
         * 
         * @param data
         *            加密数据
         * @param publicKey
         *            公钥
         * @param sign
         *            数字签名
         * 
         * @return 校验成功返回true 失败返回false
         * @throws Exception
         * 
         */
        public static boolean verify(byte[] data, String publicKey, String sign)
                throws Exception {
    
            // 解密由base64编码的公钥
            byte[] keyBytes = decryptBASE64(publicKey);
    
            // 构造X509EncodedKeySpec对象
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    
            // ALGORITHM 指定的加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    
            // 取公钥匙对象
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
    
            Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
            signature.initVerify(pubKey);
            signature.update(data);
    
            // 验证签名是否正常
            return signature.verify(decryptBASE64(sign));
        }
    
        /**
         * 生成密钥
         * 
         * @param seed
         *            种子
         * @return 密钥对象
         * @throws Exception
         */
        public static Map<String, Object> initKey(String seed) throws Exception {
            KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
            // 初始化随机产生器
            SecureRandom secureRandom = new SecureRandom();
            secureRandom.setSeed(seed.getBytes());
            keygen.initialize(KEY_SIZE, secureRandom);
    
            KeyPair keys = keygen.genKeyPair();
    
            DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
            DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
    
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put(PUBLIC_KEY, publicKey);
            map.put(PRIVATE_KEY, privateKey);
    
            return map;
        }
    
        /**
         * 默认生成密钥
         * 
         * @return 密钥对象
         * @throws Exception
         */
        public static Map<String, Object> initKey() throws Exception {
            return initKey(DEFAULT_SEED);
        }
    
        /**
         * 取得私钥
         * 
         * @param keyMap
         * @return
         * @throws Exception
         */
        public static String getPrivateKey(Map<String, Object> keyMap)
                throws Exception {
            Key key = (Key) keyMap.get(PRIVATE_KEY);
    
            return encryptBASE64(key.getEncoded());
        }
    
        /**
         * 取得公钥
         * 
         * @param keyMap
         * @return
         * @throws Exception
         */
        public static String getPublicKey(Map<String, Object> keyMap)
                throws Exception {
            Key key = (Key) keyMap.get(PUBLIC_KEY);
    
            return encryptBASE64(key.getEncoded());
        }
    
        public static byte[] decryptBASE64(String data) {
            return Base64.decodeBase64(data);
        }
    
        public static String encryptBASE64(byte[] data) {
            return new String(Base64.encodeBase64(data));
        }
    }
    复制代码

    测试代码

    复制代码
    package com.jd.order.util.encryption;
    
    import static org.junit.Assert.assertTrue;
    
    import java.util.Map;
    
    import org.junit.Test;
    
    public class DSACoderTest {
    
        @Test
        public void test() throws Exception {
            String inputStr = "abc";
            byte[] data = inputStr.getBytes();
    
            // 构建密钥
            Map<String, Object> keyMap = DSACoder.initKey();
    
            // 获得密钥
            String publicKey = DSACoder.getPublicKey(keyMap);
            String privateKey = DSACoder.getPrivateKey(keyMap);
    
            System.err.println("公钥:
    " + publicKey);
            System.err.println("私钥:
    " + privateKey);
    
            // 产生签名
            String sign = DSACoder.sign(data, privateKey);
            System.err.println("签名:
    " + sign);
    
            // 验证签名
            boolean status = DSACoder.verify(data, publicKey, sign);
            System.err.println("状态:
    " + status);
            assertTrue(status);
    
        }
    }
    复制代码

    输出

    复制代码
    公钥:
    MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd921XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=
    私钥:
    MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q
    签名:
    MCwCFGQHO9AO70cMxFTPeYqAwq7B7OFxAhRGC8A6YwFFZSfuVTAfleDof/yGug==
    状态:
    true
    复制代码

     参考地址:

    http://snowolf.iteye.com/blog/382749

    DSA算法 

  • 相关阅读:
    HDU 2089 不要62
    NOIP 2012 疫情控制
    提高工作效率的shell工具
    log loss与ctr预估
    推荐系统
    浮点数的间隙
    graphviz初学入门指南
    sparse_hash_map、dense_hash_map和sparsetable的实现细节
    每天离不开的工具vim
    安利开发利器 -- tmux
  • 原文地址:https://www.cnblogs.com/guweiwei/p/8005810.html
Copyright © 2011-2022 走看看