1、前言

对称加密:加密和解密使用同一个密钥。 对称加密算法:DES、3DES、AES等。      DES:数据加密标准,是一种使用密钥加密的块算法;      3DES:DES向AES过渡的加密算法;      AES:高级加密标准,替代DES;

对称加密的特点:

  • 加密速度快,可加密大文件;
  • 密文可逆,数据容易暴露;
  • 加密后编码找不到对应字符,出现乱码;
  • 一般结合base64使用

2、加密模式

有两种加密模式:ECB、CBC ECB:电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。

  • 优点:可以并行处理数据;
  • 缺点:同样的原文生成同样的密文, 不能很好的保护数据;

CBC:密码块链接. 每个明文块先与前一个密文块进行异或后,再进行加密。

  • 优点:同样的原文生成的密文不一样;
  • 缺点:串行处理数据.;

3、填充模式

当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则。

NoPadding:不填充;

  • 在DES加密算法下, 要求原文长度必须是8byte的整数倍
  • 在AES加密算法下, 要求原文长度必须是16byte的整数倍

PKCS5Padding:数据块的大小为8位, 不够就补足;

4、Base64算法

  • Base64算法是可读性编码算法,不是为了保护数据安全性。是为了数据可读;
  • 可读性编码不改变信息内容,只改变信息的表现形式;
  • Base64在编码过程中用到了64种字符,A-Z,a-z,0-9,“+”,“/”;

Base64算法原理:

  • base64是3个字节为1组,1个字节8位,一共24位;然后把3个字节转成4组,每组6位;缺少的2为,高位补0;这样base64的取值就控制在0-63之间了;
  • base64是3个字节为1组,位数不够时,用 = 来补齐;

说明:

  • 默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding;
  • 如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());

5、DES/AES加密解密代码示例

/**
 * @author:秋一叶
 *  DES/AES加密解密
 */
public class DesAesDemo {
    public static void main(String[] args) throws Exception {
        String input = "原文";

        //key:DES加密算法的key必须是8个字节
        String key = "abcd1234";
        //key:AES加密算法的key必须是16个字节
        String key2 = "abcdefgh12345678";

        //获取Cipher对象的算法,默认加密模式和填充模式为 ECB/PKCS5Padding
        String transformation = "DES";
        //加密模式为CBC,必须指定初始向量,初始向量中密钥长度必须是8个字节
        String transformation1 = "DES/ECB/PKCS5Padding";
        //填充模式为NoPadding,原文的长度必须是8字节的整数倍
        String transformation2 = "DES/ECB/PKCS5Padding";

        //指定加密算法
        String algorithm = "DES";

        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密后为:" + encryptDES);

        String decryptDES =  decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密后为:" + decryptDES);
    }

    /**
     * 加密
     * @param input 原文
     * @param key   密钥
     * @param transformation    获取Cipher对象的算法
     * @param algorithm         获取密钥的算法
     * @return
     */
    public static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        //获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        //创建加密规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);

        //加密模式为CBC时:初始向量,长度必须是8位
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());

        //初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE, sks);
        //加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        //对数据进行Base64编码
        String encode = Base64.encodeBase64String(bytes);
        return new String(encode);
    }

    /**
     * 解密
     * @param input
     * @param key
     * @param transformation
     * @param algorithm
     * @return
     * @throws Exception
     */
    public static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        //获取解密对象
        Cipher cipher = Cipher.getInstance(transformation);
        //指定密钥规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);

        //加密模式为CBC时:初始向量,长度必须是8位
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());

        //初始化加密模式和算法
        cipher.init(Cipher.DECRYPT_MODE, sks);
        //对数据进行Base64转码,解密
        byte[] bytes = cipher.doFinal(Base64.decodeBase64(input));
        return new String(bytes);
    }
}

说明:

  • DES和AES代码一样,只需要将指定的加密算法换一下就可以。
  • DES加密算法的key必须是8个字节,AES加密算法的key必须是16个字节。
  • 默认加密模式和填充模式为 ECB/PKCS5Padding。
  • 加密模式为CBC,必须指定初始向量,初始向量中密钥长度必须是8个字节。
  • 填充模式为NoPadding,原文的长度必须是8字节(AES是16字节)的整数倍。