.net byte转java byte_Java实现AES ECP PKCS5Padding加解密工具类

dea06264b3fe175e35a0d5c2dcc74cce.png

Java 实现一个AES/ECB/PKCS5Padding 加解密算法工具类

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

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. */@Slf4jpublic 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加解密

@Testpublic 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!

字节数组加解密

@Testpublic 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() 获得一个字符串,然后解密这个字符串,会发现解密失败哦

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

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

执行之后,发现解密失败

3f6d750f64409608ed4dfd7ea91d9ee8.png

为啥会出现这样情况呢?

  • 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);}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值