Java加密算法 DSA 和 数字签名详解编程语言

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 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。  
 * 简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。  
 * 如果数据和签名不匹配则认为验证失败!即 传输中的数据 可以不再加密,接收方获得数据后,拿到公钥与签名 验证数据是否有效  
 *   
 * @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 = "!@#$!#^$#&ZXVDF呆军工路爱着你*()_+";   
        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 verify1 = verify("aaa".getBytes(), getPublicKey(keyMap), sign);   
        System.err.println("经验证 数据和签名匹配:" + verify1);      
           
        boolean verify = verify(data, 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)); //验证签名   
    }   
       
}  

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10199.html

(0)
上一篇 2021年7月19日 10:02
下一篇 2021年7月19日 10:02

相关推荐

发表回复

登录后才能评论