百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

了解 AES 加密算法

toyiye 2024-06-06 22:12 26 浏览 0 评论

作者:枫影

出处:https://justinyan.me/post/4356


最近在开发一个简单接口的时候,因为敏感度不高所以前后台直接用对称加密解决。过程中遇到了点问题,让我想起几年前也遇到一样的问题,归根结底还是对 AES 的了解不多,所以学习了一下,其实在应用层面来说这个加密算法还是蛮简单的。

首先 AES 是一种对称加密算法,加解密都用同一个 Key,简单理解为:

明文 + Key => 密文
密文 + Key => 明文

不过实际使用中这个算法参数要更复杂些,通常会用到以下几个关键参数:

  1. Key Length: 密钥长度
  2. Key: 密钥本身
  3. IV: 初始向量
  4. Mode: 加密模式
  5. Padding: 填充方式

双方要对齐这五个参数才能完成加解密过程。我们用 node 来模拟后端加密:

const request = require('request');
const crypto = require("crypto");

const key = "your-key"; // 256 bits for AES256
const iv = "some-random-iv" // 128 bits for CBC mode

// 加密
let data = "some-strings"
cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, "utf8", "base64");
encrypted += cipher.final("base64");
console.log(encrypted)

关键代码是 cipher = crypto.createCipher('aes-256-cbc', key); ,使用 256 位长度的加密 Key,CBC 模式,初始向量 IV 为 128 位随机字符串。

AES 加密 Key 的长度一般是 128/192/256 位,唤作: AES128, AES192, AES256。这个好理解,那 iv 是用来做什么,为什么是 128 位呢?

AES 是一种分组加密算法,由比利时密码学家 Joan Daemen 和 Vincent Rijmen 设计,唤作 Rijndael。AES 规定分块长度为固定的 16 bytes,把完整数据按 16 bytes 切分后,每块进行加密,最后再把所有加密后的块拼到一起。解密的时候也一样。

如果原文本身不是 16 bytes 的整数倍时,就需要加上 Padding,而 AES 的 Padding 也有多种不同的方式。node 官方只提供了 setAutoPadding() 方法,使用 CryptoJS 则带有这些方法:

  • pad-pkcs7
  • pad-ansix923
  • pad-iso10126
  • pad-iso97971
  • pad-zeropadding
  • pad-nopadding

最后一个 pad-nopadding 自然是不填充, pad-iso10126 是当明文块少于 16 bytes 的时候,就在末尾补足,其中补足的字符里最后一个数字等于补全的字符数,剩下的就随机。

比如: [1, 2, 3, 4, 5, a, b, c, d, e] 少了 6 bytes,那可能就补成:

[1, 2, 3, 4, 5, a, b, c, d, e, 5, c, 3, G, $, 6]

其他的 padding 算法不再赘述。

接下来我们看加密模式,AES 一共有五种加密模式:

  • ECB: 电码本模式(Electronic Codebook Book)
  • CBC: 密码分组链接模式(Cipher Block Chaining)
  • CTR: 计算器模式(Counter)
  • CFB: 密码反馈模式(Cipher FeedBack)
  • OFB: 输出反馈模式(Output FeedBack)

其中 ECB 模式比较特别没有用到初始向量 IV,剩下的都比较相近。上面说 AES 是分组加密的, ECB 模式就是每一块独立加密,所以如果有两个块内容一样的话就会出现两个一样的密文。

CBC 则是前后两个分块链接的形式进行加密,后一个块跟前一个块加密后的密文进行异或运算,得到的结果再用密钥进行加密。类似于 MD5 加盐,前一块的密文就是后一块的“盐”。这样即使有两块一样的明文也会得到不一样的密文。而第一块所使用的“盐”就是 IV,初始向量(Initialization Vector)。

至此几个关键参数已介绍完毕,只要前后台把 Key, Key length, Mode, IV, Padding 都我之前遇到的问题是这样的,node 端加密时用的是老接口:

cipher = crypto.createCipher('aes-256-cbc', key);

这个接口从 node v10.0.0 开始就 deprecated 了,显然没带 IV,那这个 IV 从哪里来的呢?

 The password is used to derive the cipher key and initialization vector (IV). The value must be either a 'latin1' encoded string, a Buffer, a TypedArray, or a DataView.
 The implementation of crypto.createCipher() derives keys using the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same password always creates the same key. The low iteration count and non-cryptographically secure hash algorithm allow passwords to be tested very rapidly.
 In line with OpenSSL's recommendation to use a more modern algorithm instead of EVP_BytesToKey it is recommended that developers derive a key and IV on their own using crypto.scrypt() and to use crypto.createCipheriv() to create the Cipher object. Users should not use ciphers with counter mode (e.g. CTR, GCM, or CCM) in crypto.createCipher(). A warning is emitted when they are used in order to avoid the risk of IV reuse that causes vulnerabilities. For the case when IV is reused in GCM, see Nonce-Disrespecting Adversaries for details. 

根据 node 文档,其内部实现会拿 Key 过一遍 OpenSSL 的 EVP_BytesToKey() 然后做一次 MD5 获得 IV,理论上可以被暴力破解,所以 deprecated。(P.S. node 源码的实现是在有点绕,试图寻找 createCipher() 函数对 CBC 的实现而不得[捂脸])

使用 node 原生的这个方法搭配 crypto.createDecipher() 可以解密得出原文,因为解密的 IV 同样可以通过 Key 计算得出。但是用 iOS CommonCrypto 的接口就尴尬了,少了好几个必要参数。

参考资料

  • 什么是AES算法?(整合版)-五分钟学算法
  • Advanced Encryption Standard - Wikipedia
  • 高级加密标准 - 维基百科,自由的百科全书

作者:枫影

出处:https://justinyan.me/post/4356

相关推荐

说冲A就冲A,这个宝藏男孩冯俊杰我pick了

爱奇艺新上架了一部网剧叫《最后一个女神》。有个惊人的发现,剧里男三居然是《青春有你》的训练生冯俊杰。剧组穷,戏服没几件,冯俊杰几乎靠一件背背佳撑起了整部剧。冯俊杰快速了解一下。四川人,来自觉醒东方,人...

唐山打人嫌犯陈继志去医院就医的背后,隐藏着三个精心设计的步骤

种种迹象表明,陈继志这帮人对处理打人之后的善后工作是轻车驾熟的,他们想实施的计划应该是这样的:首先第一步与伤者进同一家医院做伤情鉴定,鉴定级别最好要比对方严重,于是两位女伤者被鉴定为轻伤,他们就要求医...

熬夜会造成神经衰弱,别再熬夜了(熬夜会加重神经衰弱吗)

长时间熬夜会出现神经衰弱,皮肤受损,超重肥胖,记忆力下降等现象……熬夜了能补回来吗?每天少睡一两个小时算熬夜吗?必须上夜班怎么办?如何减少熬夜伤害?戳图转给爱熬夜的TA!via央视新闻来源:河北省文...

落叶知秋的图片爬取(落叶知秋的图片有哪些?)

importrequestsfrombs4importBeautifulSoupimporttimeimportjsonpathimportjsonfromurllib.parsei...

小心有毒!长沙海关查获藏匿在“巧克力威化涂层”中的大麻

来源:海关发布近日,长沙黄花机场海关对一票申报为“巧克力威化涂层”的进境快件进行机检查验时,在包裹内查获封装于各独立威化饼干包装袋中的大麻230克。另从其他申报为“巧克力、儿童早餐谷物”的快件中查获藏...

钧正平:编造传播这种谣言,荒谬(钧正公司)

来源:钧正平工作室官方微博【钧评编造传播这种谣言,荒谬!】目前,乌克兰安全形势还在迅速变化之中,各方面安全风险上升。相关事件网上热度极高,倍受瞩目。然而,有一些人却借机大肆制造散播一些低级谣言,比如...

幸运角色过去了,谈一谈DNF起源的元素

总的来说伤害比上个版本强太多了,打卢克每日和团本明显能感觉的到。目前打团B套+圣耀稍微打造下应该都能随便二拖了。组队基本上都是秒秒秒(以前得强力辅助,现在随便带个毒奶都行)。单刷除了王座和顶能源阿斯兰...

DNF元素超大凉打桩测试(把括号的伤害加起来好像比较正常)

最近修练场的二觉老是很奇怪,发现以前都是习惯性先减抗然后丢二觉,结果伤害。。。直接丢二觉就正常了下面是其他技能伤害,没达到BUG线,估计问题不大。装备打造方面:全身红字加起来353(41*5+74*2...

ANSYS接触和出图技巧(ansys rough接触)

1.ANSYS后处理时如何按灰度输出云图?1)你可以到utilitymenu-plotctrls-style-colors-windowcolors试试2)直接utilitymenu-plotctr...

ANSYS有限元使用经验总结-后处理(4)

28.求塑性极限荷载时,结构的变形应该较大,建议把大变形打开。...

CFopen21.1、CFopen21.2都来了(cfile open)

[呲牙][赞][加油]

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

取消回复欢迎 发表评论:

请填写验证码