Java实现AESECPPKCS5Padding加解密工具类

编程

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

<!-- more -->

1. 工具类

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加解密

@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));

}

输出结果如:

TKrN7VKrqsAQ4JqygeHOlG21Sd3IRJ3Y11k4kOdOG4s=

Hello, 一灰灰Blog!

字节数组加解密

@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));

}

输出结果如:

// 加密的字节数组,就是乱码... 你没看错

L���R��������Δm�I��D���Y8��N�

Hello, 一灰灰Blog!

为什么有上面两种区别?

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

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

@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

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. 一灰灰Blog: https://liuyueyi.github.io/hexblog

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

2. 声明

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

  • 微博地址: 小灰灰Blog
  • QQ: 一灰灰/3302797840

3. 扫描关注

一灰灰blog

以上是 Java实现AESECPPKCS5Padding加解密工具类 的全部内容, 来源链接: utcz.com/z/516042.html

回到顶部