当前位置: 首页 > article >正文

Aes加解密

加解密概念

  • 加密
    • AES加密
      • 填充模式
      • 加密模式
      • 示例

加密

通过一系列计算将明文转换成一个密文。
加密和解密的对象通常是字节数组(有的语言动态数组类比切片

加密后的数据,可能有很多是不可读字符。通常会将其转换为可见的字符串。

  • 直接将字节数组转为16进制的字符串(一个字节8位,4位表示一个16进制数据,因此转换后的数据是转换前字节数组的2倍长度,之所以采用16进制是因为其看起来更加紧凑)
  • 将字节数组进行Base64编码

AES加密

算法相关常量在类Cipher的注释中有说明。

AES是一种对称加密算法。具体加密方式是以16字节一块进行分块加密。
如果明文长度不是16的倍数,那么则需要进行填充,这就引申出了填充模式。
其密钥长度要求为 128 位(16字节)、192(24字节) 位和 256(32字节) 位,三种,越长越安全,速度越慢

填充模式

常用填充模式:PKCS#5、PKCS#7。在Java中已经将其行为统一了。
在模式的定义上:

  • PKCS#5用于8字节块为单位的加密场景
  • PKCS#7用于非8字节块为单位的加密场景,在现代应用中更通用
    但是它们的实现方式都是类似的,剩余的字节数组长度距离加密块差几个字节,就填充几个字节,而且每一位值也是这个长度

比如剩下5字节,在AES中,是以16字节为单位,差11个字节。那么就会在这5个字节后面加11个项,而且每一项的值都是11

加密模式

AES中现在用得最多的就是CBC模式.
这种方式在加密一个块时,需要使用上一个块加密后的数据与当前明文块进行异或运算。也就是说每一个块的加密都不一样。
这就有一个点,第一个加密块前面没有数据块,所以我们需要指定一个初始向量(有的也称之为偏移量)(其长度就是一个数据块的长度)

示例

  • 加密(如果使用的是CBC模式,则需要指定初始向量(说白了就是手动创建加密块,因此也是长度为16的字节数组),
  1. 生成iv(如果是CBC模式,则需要。长度与加密块一致(16字节))
// 如果是CBC模式 首先生成iv向量(本质就是一个长度为16的字节数组,随便怎么构建)
// 可以自行创建16字节的数组,但推荐生成随机iv
// 自行构建
String ivStr = "1111111111111111"
byte[] iv = ivStr.getBytes(StandardCharsets.UTF_8);

// 生成随机iv
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[16];
secureRandom.nextBytes(iv);

IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
  1. 生成密钥
    AES密钥支持16字节、24字节、32字节(越长越安全,运算速度越慢)
    与iv类似,可以自定义密钥串,然后构建密钥对象,也可以直接生成指定长度的随机密钥
// 指定密钥串,构建密钥对象
String key = "0111111111111111";
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

// 生成指定长度的密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
  1. 创建加密器,在java中通过聚合名称指定多项配置(AES/CBC/PKCS7Padding它制定了加密算法、加密模式、填充模式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
  1. 初始化加密器。指定加密还是解密,密钥,初始向量
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
  1. 执行加解密。参数和返回都是字节数组
byte[] resByte = cipher.doFinal(s.getBytes(StandardCharsets.UTF_8));
  1. 以上加密结果可能会有一些不可读的字符,因此为了方便查看,存储,传输等,我们常常将字节数组转为16进制字符串或者Base64进行存储,传输。
    不仅是加密结果。随的的生成iv字节数组,随机生成密钥字节数组 等包含不可读字符的字节数组都可以采用这种方式进行分发,存储
  • Base64编解码
// 字节数组编码为Base64字符串
String encodedKey = Base64.getEncoder().encodeToString(encoded);

// Base64字符串解码为字节数组
byte[] keyBytes = Base64.getDecoder().decode(encodedKey);
  • 16进制编解码
// 字节数组编码为16进制字符串
public String byte2Hex(byte[] bytes) {
    int len = bytes.length;
    StringBuilder builder = new StringBuilder();
    for (int i = 0, j = 0; i < len; i++) {
        builder.append(Integer.toHexString((0xF0 & bytes[i]) >>> 4));
        builder.append(Integer.toHexString(0x0F & bytes[i]));
    }
    return builder.toString();
}

// 16进制字符串转字节数组
public byte[] hexToBytes(String s) {
    byte[] bytes = new byte[(s.length() + 1) >> 1];
    for (int i = 0, j = 0; i < bytes.length; i++) {
        int left = Character.digit(s.charAt(j++), 16) << 4;
        left = left | Character.digit(s.charAt(j++), 16);
        bytes[i] = (byte) (left & 0xff);
    }
    return bytes;
}


http://www.kler.cn/a/418151.html

相关文章:

  • MOH: MULTI-HEAD ATTENTION AS MIXTURE-OFHEAD ATTENTION
  • ASP.NET Core 负载/压力测试
  • 《运放秘籍》第二部:仪表放大器专项知识点总结
  • 【深度学习基础】一篇入门模型评估指标(分类篇)
  • 0017. shell命令--tac
  • 五:OpenStack环境准备-compute node
  • WEB攻防-通用漏洞XSS跨站MXSSUXSSFlashXSSPDFXSS
  • 如何使用Python解析从淘宝API接口获取到的JSON数据?
  • DPDK用户态协议栈-Tcp Posix API 1
  • 如何使用git fetch与git pull,在团队协作中二者有什么区别,具体案例分析并深入理解
  • AI开发-深度学习框架-PyTorch-torchnlp
  • 【看海的算法日记✨优选篇✨】第三回:二分之妙,寻径中道
  • 声音克隆技术:探索与实践 —— 从GPT-SoVITS V2到未来趋势20241201
  • 进程状态的学习
  • 【Qt中实现屏幕录制】
  • 用Leangoo领歌敏捷看板工具管理跨境电商物流出运的流程
  • redis面试复习
  • PyTorch介绍
  • 深度学习 | pytorch + torchvision + python 版本对应及环境安装
  • qt QLinearGradient详解
  • 【C++二分查找 前缀和】2333. 最小差值平方和|2011
  • Kubernetes集群操作
  • C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher
  • openwrt利用nftables在校园网环境下开启nat6 (ipv6 nat)
  • AntFlow 0.20.0版发布,增加多数据源多租户支持,进一步助力企业信息化,SAAS化
  • Python基于 Opencv+wxPython 的人脸识别上课考勤系统,附源码