200430-Java实现AES ECP PKCS5Padding加解密工具类

文章目录
  1. 1. 工具类
  2. 2. 测试case
  • II. 其他
    1. 1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
    2. 2. 声明
    3. 3. 扫描关注
  • Java 实现一个AES/ECB/PKCS5Padding 加解密算法工具类

    • 加密算法: AES
    • 模式: ECB
    • 补码方式: PKCS5Padding

    1. 工具类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    import lombok.Getter;
    import lombok.Setter;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.Base64Utils;

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.BufferedInputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.security.MessageDigest;

    /**
    * Created by @author yihui in 19:12 20/1/2.
    */
    @Slf4j
    public class EncryptUtil {
    private static final String KEY_ALGORITHM = "AES";
    /**
    * 算法/模式/补码方式
    */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final String CODE = "utf-8";

    @Setter
    @Getter
    public static String encryptKey;

    public static String encrypt(String content) {
    return encrypt(content, encryptKey);
    }

    /**
    * 加密
    *
    * @param content
    * @param key
    * @return
    * @throws Exception
    */
    public static String encrypt(String content, String key) {
    try {
    byte[] encrypted = encrypt2bytes(content, key);
    return Base64Utils.encodeToString(encrypted);
    } catch (Exception e) {
    log.error("failed to encrypt: {} of {}", content, e);
    return null;
    }
    }

    public static byte[] encrypt2bytes(String content, String key) {
    try {
    byte[] raw = key.getBytes(CODE);
    SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
    Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    return cipher.doFinal(content.getBytes(CODE));
    } catch (Exception e) {
    log.error("failed to encrypt: {} of {}", content, e);
    return null;
    }
    }

    public static String decrypt(String content) {
    try {
    return decrypt(content, encryptKey);
    } catch (Exception e) {
    log.error("failed to decrypt: {}, e: {}", content, e);
    return null;
    }
    }

    /**
    * 解密
    *
    * @param content
    * @param key
    * @return
    * @throws Exception
    */
    public static String decrypt(String content, String key) throws Exception {
    return decrypt(Base64Utils.decodeFromString(content), key);
    }

    public static String decrypt(byte[] content, String key) throws Exception {
    if (key == null) {
    log.error("AES key should not be null");
    return null;
    }

    byte[] raw = key.getBytes(CODE);
    SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
    Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, keySpec);
    try {
    byte[] original = cipher.doFinal(content);
    return new String(original, CqODE);
    } catch (Exception e) {
    log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e);
    return null;
    }
    }
    }

    请注意上面的实现,提供了两种方式

    • 一个是AES加密之后使用base64编码输出,对应的是解密base64编码的数据
    • 一个是AES加密之后,直接返回字节数组;也是直接解码字节数组

    2. 测试case

    我们提供了两个加密的文件,用于解密使用;

    base64加解密

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void testEncrypt() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    String out = EncryptUtil.encrypt(abc, key);
    System.out.println(out);

    System.out.println(EncryptUtil.decrypt(out, key));
    }

    输出结果如:

    1
    2
    TKrN7VKrqsAQ4JqygeHOlG21Sd3IRJ3Y11k4kOdOG4s=
    Hello, 一灰灰Blog!

    字节数组加解密

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void testEncryptByte() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    byte[] out = EncryptUtil.encrypt2bytes(abc, key);
    System.out.println(new String(out));

    System.out.println(EncryptUtil.decrypt(out, key));
    }

    输出结果如:

    1
    2
    3
    // 加密的字节数组,就是乱码... 你没看错
    L���R��������Δm�I��D���Y8��N�
    Hello, 一灰灰Blog!

    为什么有上面两种区别?

    如果我们将加密后的字节数组,直接 new String() 获得一个字符串,然后解密这个字符串,会发现解密失败哦

    简单修改一下上面的测试用例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void testEncryptByte() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    byte[] out = EncryptUtil.encrypt2bytes(abc, key);
    String enc = new String(out, "utf-8");
    System.out.println(enc);

    System.out.println(EncryptUtil.decrypt(enc.getBytes("utf-8"), key));
    }

    执行之后,发现解密失败

    为啥会出现这样情况呢?

    • enc = new String(out, "utf-8")enc.getBytes("utf-8") 字节数组转字符串; 字符串转字节数组这两个过程会导致最终生成的字节数组,与原始的不一致!!!

    解密远程资源的case

    最后给一个解密远程加密的二进制文件的实例case

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private void binKey(String uri, String key) throws Exception {
    // 这个文件是没有base64编码,直接上传的二进制
    URL url = new URL(uri);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    InputStream stream = connection.getInputStream();
    int lenth = connection.getContentLength();
    byte[] out = new byte[lenth];
    stream.read(out);
    stream.close();
    String ans = decrypt(out, key);
    System.out.println(ans);
    }

    public void testDe() throws Exception {
    String key = "5JRHMJn8xHnMDRXa";
    binKey("http://q8rnsprw0.bkt.clouddn.com/mwzz/b0001", key);
    }

    II. 其他

    1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

    一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

    2. 声明

    尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

    3. 扫描关注

    一灰灰blog

    QrCode

    # AES

    评论

    Your browser is out-of-date!

    Update your browser to view this website correctly. Update my browser now

    ×