目录

​AES​

​node.js实现AES加密​

​CBC模式​

​ECB模式​

​Python实现AES加密​

​CBC模式​

​ECB模式​


在渗透测试过程中,经常会碰到AES加密算法,所以趁着有时间学习下AES加密算法。

AES

     AES(Advanced Encryption Standars)高级加密标准,又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。AES是用来替换DES的,已经被广泛应用于各行各业。AES由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

     AES算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhine doll"。)

    AES是对称加密算法。AES算法基于排列和置换运算。排列是对数据重新进行安排,置换是将一个数据单元替换为另一个。AES使用几种不同的方法来执行排列和置换运算。AES是一个迭代的、对称密钥分组的密码。AES 加密有 AES-128、AES-192、AES-256 三种。分别对应三种密钥长度 128bits(16字节)、192bits(24字节)、256bits(32字节)。当然,密钥越长,安全性越高,加解密花费时间也越长。默认的是AES-128,其安全性完全够用。与公共密钥加密使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换和替换输入数据。

AES加密_字符串

 AES是基于数据块的加密方式,也就是说,每次处理的数据是一块(16字节),当数据不是16字节的倍数时会进行填充,这就是所谓的分组密码(区别于基于比特位的流密码),16字节是分组长度。

在用脚本实现AES加密算法过程中,有几个重要的参数:


  • 秘钥key:有三种长度,分别是 16字节、24字节、32字节
  • 偏移量iv:ECB模式不需要偏移量iv。偏移量的取值,至少 16 位,或者为 16 的倍数。
  • 填充模式:有五个,分别为Pkcs7、Iso97971、AnsiX923、Iso10126、ZeroPadding。其中Pkcs7是默认的填充模式。
  • 加密模式:有五个,分别为:ECB、CBC、CTR、CFB、 OFB

AES的加密模式有五个:


  • 电码本模式(ECB:Electronic Codebook Book):是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。该模式不需要偏移量iv
  • 密码分组链接模式(CBC:Cipher Block Chaining):是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度。
  • 计算器模式(CTR:Counter);
  • 密码反馈模式(CFB:Cipher FeedBack):实际上是一种反馈模式,目的也是增强破解的难度
  • 输出反馈模式(OFB:Output FeedBack):实际上是一种反馈模式,目的也是增强破解的难度

其中 ECB 和 CBC 模式用的比较多,并且 ECB 模式不需要偏移量iv。

node.js实现AES加密

node.js实现AES需要安装 crypto-js 库,安装方法:cnpm install  crypto-js

AES加密_字符串_02

CBC模式

var CryptoJS = require("crypto-js");
//AES加密
function encrypt(text) {
return CryptoJS.AES.encrypt(
text,
CryptoJS.enc.Utf8.parse(key),
{
iv: CryptoJS.enc.Utf8.parse('0102030405060708'), //偏移向量,如果加密模式是ECB的话,则不需要iv
mode: CryptoJS.mode.CBC, //加密模式
padding: CryptoJS.pad.Pkcs7 //填充
}).toString()
}
//AES解密
function decrypt(text) {
var result = CryptoJS.AES.decrypt(
text,
CryptoJS.enc.Utf8.parse(key),
{
iv: CryptoJS.enc.Utf8.parse('0102030405060708'), //偏移向量,如果加密模式是ECB的话,则不需要iv
mode: CryptoJS.mode.CBC, //加密模式
padding: CryptoJS.pad.Pkcs7 //填充
})
return result.toString(CryptoJS.enc.Utf8)
}
var key = "8Vh1Py0Eg8Ks8Ji7"; //秘钥key
var text = "123456"; //要加密的字符串
var text_encode = encrypt(text); //加密后的字符串
console.log("加密的字符串为:",decrypt(text_encode)); //打印出解密后的字符串
console.log("加密后的字符串为:",text_encode); //打印出加密后的字符串

ECB模式

var CryptoJS = require("crypto-js");
//AES加密
function encrypt(text) {
return CryptoJS.AES.encrypt(
text,
CryptoJS.enc.Utf8.parse(key),
{
// iv: "0102030405060708", //偏移向量,如果加密模式是ECB的话,则不需要iv
mode: CryptoJS.mode.ECB, //加密模式
padding: CryptoJS.pad.Pkcs7 //填充
}).toString()
}
//AES解密
function decrypt(text) {
var result = CryptoJS.AES.decrypt(
text,
CryptoJS.enc.Utf8.parse(key),
{
// iv: "0102030405060708", //偏移向量,如果加密模式是ECB的话,则不需要iv
mode: CryptoJS.mode.ECB, //加密模式
padding: CryptoJS.pad.Pkcs7 //填充
})
return result.toString(CryptoJS.enc.Utf8)
}
var key = "8Vh1Py0Eg8Ks8Ji7"; //秘钥key
var text = "123456"; //要加密的字符串
var text_encode = encrypt(text); //加密后的字符串
console.log("加密的字符串为:",decrypt(text_encode)); //打印出解密后的字符串
console.log("加密后的字符串为:",text_encode); //打印出加密后的字符串

Python实现AES加密

python需要安装 pycryptodome 库,装方法:pip install   pycryptodome

AES加密_偏移量_03

CBC模式

import base64
from Crypto.Cipher import AES
# 密钥(key), 密斯偏移量(iv) CBC模式加密

def AES_Encrypt(key, data):
vi = '0102030405060708'
pad = lambda s: s + (16 - len(s)%16) * chr(16 - len(s)%16)
data = pad(data)
# 字符串补位
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
encryptedbytes = cipher.encrypt(data.encode('utf8'))
# 加密后得到的是bytes类型的数据
encodestrs = base64.b64encode(encryptedbytes)
# 使用Base64进行编码,返回byte字符串
enctext = encodestrs.decode('utf8')
# 对byte字符串按utf-8进行解码
return enctext


def AES_Decrypt(key, data):
vi = '0102030405060708'
data = data.encode('utf8')
encodebytes = base64.decodebytes(data)
# 将加密数据转换位bytes类型数据
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
text_decrypted = cipher.decrypt(encodebytes)
unpad = lambda s: s[0:-s[-1]]
text_decrypted = unpad(text_decrypted)
# 去补位
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted


key = '8Vh1Py0Eg8Ks8Ji7'
data = '123456'
AES_Encrypt(key, data)
enctext = AES_Encrypt(key, data) #加密后的字符串
text_decrypted = AES_Decrypt(key, enctext) #加密的字符串
print("加密的字符串为:",text_decrypted)
print("加密后的字符串为:",enctext)

ECB模式

from Crypto.Cipher import AES
import base64
BLOCK_SIZE = 16 # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
#加密函数
def aesEncrypt(key, data):
'''
AES的ECB模式加密方法
:param key: 密钥
:param data:被加密字符串(明文)
:return:密文
'''
key = key.encode('utf8')
# 字符串补位
data = pad(data)
cipher = AES.new(key, AES.MODE_ECB)
# 加密后得到的是bytes类型的数据,使用Base64进行编码,返回byte字符串
result = cipher.encrypt(data.encode())
encodestrs = base64.b64encode(result)
enctext = encodestrs.decode('utf8')
return enctext
#解密函数
def aesDecrypt(key, data):
'''
:param key: 密钥
:param data: 加密后的数据(密文)
:return:明文
'''
key = key.encode('utf8')
data = base64.b64decode(data)
cipher = AES.new(key, AES.MODE_ECB)
# 去补位
text_decrypted = unpad(cipher.decrypt(data))
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted
if __name__ == '__main__':
key = '8Vh1Py0Eg8Ks8Ji7'
data = '123456'
enctext = aesEncrypt(key, data)
text_decrypted = aesDecrypt(key, enctext)
print("加密的字符串为:",text_decrypted)
print("加密后的字符串为:",enctext)