java ASE CBC 128 对称加密

发布时间 2023-04-17 10:56:33作者: vx_guanchaoguo0

使用CBC 128 PKCS5Padding

  • 对称加密算法的工作模式(mode of operation)
    • ECB(Electronic CodeBook):电子密码本模式,是一种最简单的块加密模式。它将明文分成若干个块,每个块都独立地进行加密。虽然 ECB 简单,但是它存在很多的安全问题,不推荐使用。
    • CBC(Cipher Block Chaining):加密块链模式,是目前应用最广泛的加密模式之一。它需要一个初始向量(IV)来保证第一个块的正确性,之后每个加密块的输出都会与下一个明文块进行异或操作,从而增强了加密的随机性和安全性。
    • CFB(Cipher FeedBack):加密反馈模式,是一种将分组密码转换为自同步流密码的方式。它需要一个初始向量(IV)来保证第一个输出的正确性,之后,每个输出会被用作下一轮加密的输入。
    • OFB(Output FeedBack):输出反馈模式,是一种将分组密码转换为自同步流密码的方式。它也需要一个初始向量(IV)来保证第一个输出的正确性,之后,每个输出会被用作下一轮加密的输入,不同于 CFB,OFB 的输出与明文无关。
    • CTR(Counter):计数器模式,将块加密算法转换为流加密算法。CTR 模式在加密时会使用一个计数器来分配不同的加密密钥,从而保证每个输出都是独立的,不同于 OFB 和 CFB。
    • GCM(Galois/Counter Mode):是一种对于加密和完整性提供同时保证的加密模式。它将 CTR 模式与 GHASH 算法相结合,从而实现了高效的身份认证和加密。
  • 密钥长度
    • AES-128:使用 128 位密钥,需要 10 轮轮函数迭代;
    • AES-192:使用 192 位密钥,需要 12 轮轮函数迭代;
    • AES-256:使用 256 位密钥,需要 14 轮轮函数迭代。
  • 填充长度
  • PKCS5Padding:与 PKCS7Padding 类似,但是只支持 8 个字节的填充块;
  • PKCS7Padding:与 PKCS5Padding 类似,但是支持任意长度的填充块;
  • NoPadding:不进行任何填充,明文必须是块大小的整数倍,否则需要手动进行填充(例如使用 \0 或空格来填充)。

hutool

private static final String keyStr = "2513e9c533c14271";
private static final String IV_KEY = "a1bc8a52eacecebe";
String content = "{ \"secretKey\": \"2513e9c533c14271a1bc8a52eacecebe\", \"appKey\": \"19b9257a1f464e93b087af9d12572ce1\"}";
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, keyStr.getBytes(), IV_KEY.getBytes());
System.out.println("加密后的数据:" + Base64.encode(aes.encrypt(content.getBytes())) + "\n");

java sdk

private static final String keyStr = "2513e9c533c14271";
private static final String IV_KEY = "a1bc8a52eacecebe";
String content = "{ \"secretKey\": \"2513e9c533c14271a1bc8a52eacecebe\", \"appKey\": \"19b9257a1f464e93b087af9d12572ce1\"}";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(keyStr.getBytes(), "AES");
IvParameterSpec iv = new IvParameterSpec(IV_KEY.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(content.getBytes("utf-8"));
System.out.println("加密后的数据:" + (new BASE64Encoder()).encode(encrypted).replaceAll("\n","") + "\n");