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

  • 相关阅读:
    MySQL数据类型
    Linux网络编程:客户端/服务器的简单实现
    初学JAVA
    依据函数名字符串执行函数
    Windows Server 2012学习文档
    DELPHI WEBSERVICE
    常用函数、常量、类型记录
    CAD2007_DWG转PDF
    MCU_头文件编写
    MCU_存储器
  • 原文地址:https://www.cnblogs.com/at0x7c00/p/7688082.html
Copyright © 2011-2022 走看看