您的位置:首页 > 编程语言 > Java开发

四、DSA

2015-12-03 16:42 519 查看
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;  

import sun.misc.BASE64Decoder;  

import sun.misc.BASE64Encoder;  

  

/** 

 * DSA-Digital Signature Algorithm。 

 * 简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。 

 * 如果数据和签名不匹配则认为验证失败!即 传输中的数据 可以不再加密,接收方获得数据后,拿到公钥与签名 验证数据是否有效 

 * @author stone 

 * @date 2014-03-11 09:50:51 

 */  

public class DSA {  

    //不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名  

    /*public static final String KEY_ALGORITHM = "RSA"; 

    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";*/  

    public static final String KEY_ALGORITHM = "DSA";  

    public static final String SIGNATURE_ALGORITHM = "DSA";  

    public static final String DEFAULT_SEED = "$%^*%^()(HJG8awfjas7"; //默认种子  

    public static final String PUBLIC_KEY = "DSAPublicKey";  

    public static final String PRIVATE_KEY = "DSAPrivateKey";  

      

    public static void main(String[] args) throws Exception {  

        String str = "!@#$!#^$#&ZXVDFegrhtfmhngb放烟花*()_+";  

        byte[] data = str.getBytes();  

        Map<String, Object> keyMap = initKey();// 构建密钥  

        PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY);  

        PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY);  

        System.out.println("私钥format:" + privateKey.getFormat());  

        System.out.println("公钥format:" + publicKey.getFormat());  

        // 产生签名  

        String sign = sign(data, getPrivateKey(keyMap));  

        // 验证签名   

        boolean verify = verify("!@#$!#^$#&ZXVDFegrhtfmhngb放烟花*()_+".getBytes(), getPublicKey(keyMap), sign); // 原数据、公钥、私钥对原数据名

        System.err.println("经验证 数据和签名匹配:" + verify);   

    }  

      

    /**   

     * 生成密钥   

     *    

     * @param seed 种子   

     * @return 密钥对象   

     * @throws Exception   

     */  

    public static Map<String, Object> initKey(String seed) throws Exception {  

        System.out.println("生成密钥");  

        KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);  

        SecureRandom secureRandom = new SecureRandom();     

        secureRandom.setSeed(seed.getBytes());   

        //Modulus size must range from 512 to 1024 and be a multiple of 64  

        keygen.initialize(640, secureRandom);    

        KeyPair keys = keygen.genKeyPair();  

        PrivateKey privateKey = keys.getPrivate();  

        PublicKey publicKey = keys.getPublic();  

        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()); //base64加密私钥  

    }     

    

    /**   

     * 取得公钥   

     * @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()); //base64加密公钥  

    }     

      

    /** 

     *  用私钥对信息进行数字签名 

     * @param data  加密数据 

     * @param privateKey 私钥-base64加密的 

     * @return  

     * @throws Exception 

     */  

    public static String sign(byte[] data, String privateKey) throws Exception {  

        System.out.println("用私钥对信息进行数字签名");  

        byte[] keyBytes = decryptBASE64(privateKey);  

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);  

        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);  

        PrivateKey priKey = factory.generatePrivate(keySpec);//生成 私钥  

        //用私钥对信息进行数字签名  

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  

        signature.initSign(priKey);  

        signature.update(data);  

        return encryptBASE64(signature.sign());  

    }  

      

    /** 

     * BASE64Encoder 加密 

     * @param data 要加密的数据 

     * @return 加密后的字符串 

     */  

    private static String encryptBASE64(byte[] data) {  

        BASE64Encoder encoder = new BASE64Encoder();  

        String encode = encoder.encode(data);  

        return encode;  

    }  

      

    /** 

     * BASE64Decoder 解密 

     * @param data 要解密的字符串 

     * @return 解密后的byte[] 

     * @throws Exception  

     */  

    private static byte[] decryptBASE64(String data) throws Exception {  

        BASE64Decoder decoder = new BASE64Decoder();  

        byte[] buffer = decoder.decodeBuffer(data);  

        return buffer;  

    }  

      

    /** 

     * 校验数字签名 

     * @param data 加密数据 

     * @param publicKey 

     * @param sign 数字签名 

     * @return 

     * @throws Exception 

     */  

    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {  

        byte[] keyBytes = decryptBASE64(publicKey);   

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  

        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)); //验证签名  

    }  

      

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息