AES加密过程
- 初始轮(Initial Round):
- 将明文分组与初始轮密钥(Round Key)进行XOR运算。
- 轮运算(Rounds):
- AES算法中的加密运算是由多轮执行的,每一轮都包含四个基本步骤:字节代换(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。
- 字节代换(SubBytes):通过一个固定的S盒(Substitution Box)将每个字节替换为另一个字节。
- 行移位(ShiftRows):对每一行进行循环移位。第一行不变,第二行向左移动一位,第三行向左移动两位,第四行向左移动三位。
- 列混淆(MixColumns):将每一列视为多项式,然后与一个固定的矩阵进行乘法,结果取模AES的模多项式。
- 轮密钥加(AddRoundKey):每一轮使用的轮密钥与状态矩阵进行逐比特的XOR运算。
-
- 最终轮(Final Round):
- 在最后一轮中,省略列混淆步骤,只执行字节代换、行移位和轮密钥加。
- 输出密文(Cipher Text):
- 经过多轮处理后的状态矩阵即为加密后的密文。
具体步骤
1.定义初始常量
初始常量不同,得到的密钥也不同,我们先规定一个初始常量
#轮常数
cons1="10000000"
cons2="00110000"
# 置换盒
S_Box = [['9', '4', 'A', 'B'],
['D', '1', '8', '5'],
['6', '2', '0', '3'],
['C', 'E', 'F', '7']]
# 逆置换盒
S_deBox = [['A', '5', '9', 'B'],
['1', '7', '8', 'F'],
['6', '0', '2', '3'],
['C', '4', 'D', 'E']]
mixMatrix = [['1', '4'], ['4', '1']]
deMixMatrix = [['9', '2'], ['2', '9']]
2.密钥扩展
原来的密钥需要生成多对子密钥,分别作为各轮加密步骤的子密钥。
==将16位密钥分为左右两部分,每一部分各8位。记原始密钥为第0个密钥。==
在计算第i
个密钥时,首先将第i-1
个密钥的右半部分(8位)进行左循环移位,即将第i-1
个密钥的右半部分的左右4位进行交换,再将左循环移位后的第i-1
个密钥的右半部分(8位)进行S盒置换。
进行S盒置换后需要与轮常数进行异或,S-AES的轮常数定义为:第一轮加密的轮常数是【1000 0000】,第二轮加密的轮常数是【0011 0000】。
上述步骤就是示意图中函数g的步骤,将第i-1个密钥的右半部分(8位)执行完上述步骤后得到g(第i-1个密钥的右半部分),将其与第i-1个密钥的左半部分(8位)进行异或得到第i个密钥的左半部分。
第i个密钥的右半部分由第i个密钥的左半部分与第i-1个密钥的右半部分进行异或得到。
具体实现:
#输入初始密钥,输出扩展之后的密钥
def expandKey(key: str, cons: str, Box: List[List[str]])-> str:
rightKey = key[8:]
leftKey = key[0:8]
# 左边的密钥由右半部分g(i-1)与左半部分异或得到
resLeft=xor(G(rightKey,cons,Box),leftKey)
# 第i个密钥的右半部分由第i个密钥的左半部分与第i-1个密钥的右半部分进行异或得到
resRight=xor(resLeft,rightKey)
return resLeft+resRight
#密钥扩展的g函数,
def G(byteText: str, cons: str, Box: List[List[str]]) -> str:
#第一步进行左循环移位,将左右两个进行互换
resText=byteText[4:]+byteText[0:4]
#第二步进行S盒替代
index = 0
result = ""
while index < len(resText):
i = int(resText[index:index + 2], 2)
j = int(resText[index + 2:index + 4], 2)
result += Box[i][j]
index += 4
# 十六进制转换二进制
result = bin(int(result, 16))[2:].zfill(8)
#第三步,与轮常数进行异或
result=xor(result,cons)
return result
测试
#密钥扩展确认
cyberText="1010011100111011"
print("密钥扩展确认")
print("第一轮加密:" + expandKey(cyberText,cons1,S_Box))
print("第二轮加密:" + expandKey(expandKey(cyberText,cons1,S_Box), cons2, S_Box))
结果
3.轮密相加
第零轮加密,也就是对状态矩阵与密钥进行逐位的异或操作
# 轮密钥加密:逐位进行异或操作 输入两个二进制字符串,输出结果=>二进制字符串
def xor(text1, text2):
i = 0
restext = ""
while i < len(text1):
if text1[i] == text2[i]:
restext += "0"
else:
restext += "1"
i += 1
return restext
4.半字节代替
# 半字节替代,传入二进制字符串,返回二进制字符串
def halfByteReplace(text, Box):
index = 0
result = ""
while index < len(text):
i = int(text[index:index + 2], 2)
j = int(text[index + 2:index + 4], 2)
result += Box[i][j]
index += 4
# 十六进制转换二进制
result = bin(int(result, 16))[2:].zfill(16)
return result
因为在这里用到了置换盒,我们需要保证正置换盒和逆置换盒之间是匹配的,所以需要进行测试:
# 置换盒测试程序
plainText = bin(int("8A1C", 16))[2:]
print("置换盒测试")
print(plainText)
print(hex(int(halfByteReplace(plainText, S_Box), 2)))
print(hex(int(halfByteReplace(halfByteReplace(plainText, S_Box), S_deBox), 2)))
运行可以通过
置换盒测试
1000101000011100
0x604c
0x8a1c
5.行位移
# 左循环移位,传入二进制字符串,返回二进制字符串
def left_shift(text):
stateMartix = toStateMartix(text)
# 交换
tem = stateMartix[1][0]
stateMartix[1][0] = stateMartix[1][1]
stateMartix[1][1] = tem
return reStateMartix(stateMartix)
测试程序
# 行移位测试程序
print("行移位测试")
resText = halfByteReplace(plainText, S_Box)
print(hex(int(left_shift(resText), 2)))
行移位测试
0x6c40
6.列混淆