• JAVA加密算法(DSA)


    DSA 
    DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!也就是说传输中的数据可以不再加密,接收方获得数据后,拿到公钥与签名比对数据是否有效! 

    通过java代码实现如下:Coder类见 java加密技术(一) 
    Java代码 

    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.spec.PKCS8EncodedKeySpec;   
    import java.security.spec.X509EncodedKeySpec;   
    import java.util.HashMap;   
    import java.util.Map;   
      
      
    /**  
    * DSA安全编码组件  
    *   
    */  
    public abstract class DSACoder extends Coder {   
        /**  
         * 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。  
         *   
         * <code>  
         * public static final String KEY_ALGORITHM = "RSA";  
         * public static final String SIGNATURE_ALGORITHM = "MD5withRSA";  
         * </code>  
         **/  
        public static final String KEY_ALGORITHM = "DSA";   
        public static final String SIGNATURE_ALGORITHM = "DSA";   
      
        /**  
         * 默认种子  
         */  
        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(KEY_ALGORITHM);   
      
            // 取私钥匙对象   
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);   
      
            // 用私钥对信息生成数字签名   
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);   
            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);   
      
            // KEY_ALGORITHM 指定的加密算法   
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);   
      
            // 取公钥匙对象   
            PublicKey pubKey = keyFactory.generatePublic(keySpec);   
      
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);   
            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(KEY_ALGORITHM);   
            // 初始化随机产生器   
            SecureRandom secureRandom = new SecureRandom();   
            secureRandom.setSeed(seed.getBytes());   
            keygen.initialize(1024, secureRandom);   
      
            KeyPair keys = keygen.genKeyPair();   
      
            PublicKey publicKey = keys.getPublic();   
            PrivateKey privateKey = 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());   
        }   
    }  
    
    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.spec.PKCS8EncodedKeySpec; 
    import java.security.spec.X509EncodedKeySpec; 
    import java.util.HashMap; 
    import java.util.Map; 
    
    
    /** 
    * DSA安全编码组件 
    * 
    */ 
    public abstract class DSACoder extends Coder { 
    /** 
    * 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。 
    * 
    * <code> 
    * public static final String KEY_ALGORITHM = "RSA"; 
    * public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; 
    * </code> 
    **/ 
    public static final String KEY_ALGORITHM = "DSA"; 
    public static final String SIGNATURE_ALGORITHM = "DSA"; 
    
    /** 
    * 默认种子 
    */ 
    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(KEY_ALGORITHM); 
    
    // 取私钥匙对象 
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); 
    
    // 用私钥对信息生成数字签名 
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 
    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); 
    
    // KEY_ALGORITHM 指定的加密算法 
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 
    
    // 取公钥匙对象 
    PublicKey pubKey = keyFactory.generatePublic(keySpec); 
    
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 
    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(KEY_ALGORITHM); 
    // 初始化随机产生器 
    SecureRandom secureRandom = new SecureRandom(); 
    secureRandom.setSeed(seed.getBytes()); 
    keygen.initialize(1024, secureRandom); 
    
    KeyPair keys = keygen.genKeyPair(); 
    
    PublicKey publicKey = keys.getPublic(); 
    PrivateKey privateKey = 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()); 
    } 
    } 
    
    
    不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名,但要注意成对出现: 
    public static final String KEY_ALGORITHM = "RSA"; 
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; 
    
    再给出一个测试类: 
    Java代码 
    import static org.junit.Assert.*;   
      
    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);   
      
        }   
      
    }  
    
    import static org.junit.Assert.*; 
    
    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); 
    
    }
    }

    控制台输出: 
    Console代码 
    公钥:   
    MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp   
    RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn   
    xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE   
    C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ   
    FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo   
    g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv   
    5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9   
    21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=   
      
    私钥:   
    MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2   
    USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4   
    O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC   
    ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB   
    gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR   
    kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q   
      
    签名:   
    MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=   
      
    状态:   
    true  

    公钥: 
    MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp 
    RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn 
    xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE 
    C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ 
    FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo 
    g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv 
    5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9 
    21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo= 

    私钥: 
    MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2 
    USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4 
    O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC 
    ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB 
    gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR 
    kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q 

    签名: 
    MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs= 

    状态: 
    true 

  • 相关阅读:
    js试题
    JavaScript 实现removeElement函数
    关于优化
    变量申明的提升,闭包,作用域,this,运算符优先级详细举例及讲解
    前端架构:MVC以及MVVM MVP介绍
    JavaScript事件委托
    各种浏览器的Hack写法(chrome firefox ie等)
    vue页面跳转不刷新时created只执行一次
    iview-admin添加的路由为英文
    vue中使用moment时间戳
  • 原文地址:https://www.cnblogs.com/azhqiang/p/4562724.html
Copyright © 2020-2023  润新知