Copyright © 2018 Joyce_BY
All rights reserved.
Contact by Yagnes126@gmail.com
本文目的及实验环境
1、实现128-bit的AES加解密过程
2、python3.7.0,windows10
原理及代码
整体原理图
注意:最后一轮变换没有mixcolumn过程。
CODE
ef aes_encrypt(text,key): #ok
# input text is a block
state = create_block(text)
# k0 xor plaintext
state = xor(state,create_block(key[0]))
# 10 rounds
for i in range(1,11):
state = aes_encrypt_round(i,state,create_block(key[i]))
# return ciphertext in orginal order:
return create_block(state)
def aes_decrypt(text,key): #ok
# input text is a block
state = create_block(text)
# k0 xor plaintext
state = xor(state,create_block(key[10]))
# 10 rounds
for i in range(1,11):
state = aes_decrypt_round(i,state,create_block(key[10-i]))
# return plaintext
return create_block(state)
每一轮的算法
(0)此处明文和密钥长度都为128比特,则根据AES算法知道应该加密10轮;
(1)数据分组
将一开始传入AES算法模块的数据,以BYTE为单位如下图顺序排列为4*4的矩阵
编排函数如下
def create_block(message): #ok
# arrange byte stream into a matrix
# message is a list of hex values
create = []
seq = [0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15]
# 16 bytes:
for i in range(16):
create.append(message[seq[i]])
return create
AES加密轮的算法
(1)初始轮:第0轮,我们将明文矩阵与初始密钥k0做异或运算,结果传入第一轮加密模块。
第1-10轮:对第i轮按顺序执行字节替换、字节移位、列混淆(除第10轮)、轮密钥相加;
CODE
def aes_encrypt_round(i,state,roundkey): #ok
# byte substitution
state = substitution(state,0)
# byte rotation
state = rotation(state,0)
# if not final round: mix column
if i != 10:
state = mixcolumn(state,0)
# round key xor
state = xor(state,roundkey)
return state
AES解密轮的算法
过程相同,顺序不同。
初始轮:第0轮,我们将明文矩阵与初始密钥k0做异或运算,结果传入第一轮加密模块。
第1-10轮:对第i轮按顺序执行字节移位、字节替换、轮密钥相加、列混淆(除第10轮);
CODE
def aes_decrypt_round(i,state, roundkey): #ok
# inv byte rotation
state = rotation(state,1)
# inv byte substitution
state = substitution(state,1)
# round key xor
state = xor(state,roundkey)
# if not first round: inv mix column
if i != 10:
state = mixcolumn(state,1)
return state
A、字节替代 Byte Substitution
非线性的字节替代,独立对每个字节进行运算,包括两个具体过程:
(a)对字节x在有限域GF(2^8)上求乘法逆,得到x-1,0x00的逆为其本身;
(b)在GF(2)上进行affine transform:y = Ax^-1+b,A为矩阵,b为向量,定值。
在实现的时候利用S盒打表实现,状态矩阵中的元素按照下面的方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,取出S盒中对应的行的元素作为输出。
解密通过逆S盒实现。
CODE
def substitution(state,mode): #ok
sbox = [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1</