zoukankan      html  css  js  c++  java
  • Java加密与解密笔记(二) 对称加密

    前面的仅仅是做了编码或者摘要,下面看看真正的加密技术。

    DES

    public class DESUtil {
    
        static final String ALGORITHM = "DES";
        
        /**
         * 生成文本格式的DES Key
         * @return
         * @throws Exception
         */
        public static String getKey() throws Exception{
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            generator.init(new SecureRandom());//加盐 
            return Base64Util.encode(generator.generateKey().getEncoded());
        }
        
        /**
         * 从文本 格式DES Key转换成SecretKey对象
         * @param key
         * @return
         */
        public static SecretKey parseKeyFromString(String key)throws Exception{
            DESKeySpec desKeySpec = new DESKeySpec(Base64Util.decode(key));
            SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
            SecretKey secretKey = factory.generateSecret(desKeySpec);
            return secretKey;
        }
        
        /**
         * DES 加密
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static String encrypt(String data,String key)throws Exception{
            SecretKey secretKey = parseKeyFromString(key);
            Cipher cipher = Cipher.getInstance(ALGORITHM); 
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));
            return Base64Util.encode(bytes);
        }
        
        /**
         * DES 解密
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static String decrypt(String data,String key)throws Exception{
            SecretKey secretKey = parseKeyFromString(key);
            Cipher cipher = Cipher.getInstance(ALGORITHM); 
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] bytes = cipher.doFinal(Base64Util.decode(data));
            return new String(bytes,"UTF-8");
        }
        
        public static void main(String[] args)throws Exception {
            String str = "Hello,DES";
            String key = getKey();
            System.out.println("原文:" + str);
            System.out.println("密钥:" + key);
            String encryptedStr = encrypt(str, key);
            System.out.println("加密后:" + encryptedStr);
            String decryptedStr = decrypt(encryptedStr, key);
            System.out.println("解密后:" + decryptedStr);
        }
        
    }

    类似DESKeySpec,Java中很多*KeySpec的类都实现了KeySpec的空接口,Java只关心某个类是否是一种Key的实现,至于具体如何实现的是具体加密解密算法要关心的。

    再次看到Base64的身影,由此可以看出,Base64其实充当着字符串和byte数组之间的转换器,真实的的密钥数据其实是byte类型的,但是在阅读和传输过程中字符串比较方便,所以我们能看到的很多密钥信息其实都是Base64编码。

    Ciper为密文工具类,它是一个很高级的抽象类,有很多种Cipher的实现,可以通过Cipher.getInstance()方法获取到。

    getInstance方法接收的算法名称非常多:

    测试:

    原文:Hello,DES
    密钥:8ePQx0m1I4k=
    加密后:bM06WR8OIL2sQOB8SUSXRA==
    解密后:Hello,DES

     AES

    AES是DES的升级版,解决了DES的很多不足,上述DES代码改成AES的改动很小:

    static final String ALGORITHM = "AES";    
       /**
         * 从文本 格式AES Key转换成SecretKey对象
         * @param key
         * @return
         */
        public static SecretKey parseKeyFromString(String key)throws Exception{
            SecretKey secretKey = new SecretKeySpec(Base64Util.decode(key), ALGORITHM);
            return secretKey;
        }    

     PBE

    PBE与DES、AES同属对称加密,不同之处在于其密钥可以由用户管理,即密钥可以不用通过KeyGenerator来生成,可以是任意字符。为了增强安全性,PBE强制必须要有参数(java.security.spec.AlgorithmParameterSpec),可以理解为强制加盐,否则将报错。

    public class PBEUtil {
    
        static final String ALGORITHM = "PBEWITHMD5andDES";
        
        private static SecretKey parseKeyFromString(String key) throws Exception{
            PBEKeySpec pbeKey = new PBEKeySpec(key.toCharArray());
            SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
            return factory.generateSecret(pbeKey);
        }
        
        /**
         * PBE 加密
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static String encrypt(String data,String key,byte[] salt)throws Exception{
            SecretKey secretKey = parseKeyFromString(key);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            PBEParameterSpec params = new PBEParameterSpec(salt, 100);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey,params);
            byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));
            return Base64Util.encode(bytes);
        }
        
        /**
         * DES 解密
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static String decrypt(String data,String key,byte[] salt)throws Exception{
            SecretKey secretKey = parseKeyFromString(key);
            Cipher cipher = Cipher.getInstance(ALGORITHM); 
            PBEParameterSpec params = new PBEParameterSpec(salt, 100);
            cipher.init(Cipher.DECRYPT_MODE, secretKey,params);
            byte[] bytes = cipher.doFinal(Base64Util.decode(data));
            return new String(bytes,"UTF-8");
        }
        
        public static void main(String[] args)throws Exception {
            String str = "Hello,PBE";
            String key = "abc";
            byte[] salt = new byte[8];
            new Random().nextBytes(salt);
            System.out.println("原文:" + str);
            System.out.println("密钥:" + key);
            String encryptedStr = encrypt(str, key,salt);
            System.out.println("加密后:" + encryptedStr);
            String decryptedStr = decrypt(encryptedStr, key,salt);
            System.out.println("解密后:" + decryptedStr);
        }
        
    }

    参考资料:

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

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

  • 相关阅读:
    【C++】资源管理
    【Shell脚本】逐行处理文本文件
    【算法题】rand5()产生rand7()
    【Shell脚本】字符串处理
    Apple iOS产品硬件参数. 不及格的程序员
    与iPhone的差距! 不及格的程序员
    iPhone游戏 Mr.Karoshi"过劳死"通关. 不及格的程序员
    XCode V4 发布了, 苹果的却是个变态. 不及格的程序员
    何时readonly 字段不是 readonly 的?结果出呼你想象!!! 不及格的程序员
    object file format unrecognized, invalid, or unsuitable Command 不及格的程序员
  • 原文地址:https://www.cnblogs.com/at0x7c00/p/7688082.html
Copyright © 2011-2022 走看看