AES加解密算法 Python实现
实现了AES加解密算法。初次尝试,能力有限,代码粗糙,仅供交流学习。五种工作模式也实现了,有需要的可以私聊我。
Talk is cheap. Show me the code.
def HexToListTranslation(Hex="0123456789abcdeffedcba9876543210"):
List=[]
for p in range(0,len(Hex),2):
listElement="0x"+Hex[p]+Hex[p+1]
List.append(listElement)
return(List)
def ListToHexTranslation(List=["0x01","0x23","0x45","0x67","0x89","0xab","0xcd","0xef","0xfe","0xdc","0xba","0x98","0x76","0x54","0x32","0x10"]):
Hex=""
for i in range(len(List)):
if(len(List[i][2:])==1):
Hex=Hex+"0"+List[i][2:]
else:
Hex=Hex+List[i][2:]
return(Hex)
#计算在GF(2^8)中的乘法逆元
def poly_multip(a=0x95,b=0x11b):
sum=0
for i in range(0,len(bin(b))-2):
if(bin(b)[len(bin(b))-i-1]=="1"):
sum^=a<<i
else:
continue
return hex(sum)
def poly_div(a=0x95,b=0x11b):
div=0
mod=0
if(b>a):
if(a==1):
div=b
return (hex(div),hex(mod))
else:
while(True):
if(len(bin(b))-len(bin(a))>=0):
shift=len(bin(b))-len(bin(a))
div=div^(1<<shift)
b=b^(a<<shift)
else:
mod=b
break
return (hex(div),hex(mod))
else:
if(b==1):
div=a
return (hex(div),hex(mod))
else:
while(True):
if(len(bin(a))-len(bin(b))>=0):
shift=len(bin(a))-len(bin(b))
div=div^(1<<shift)
a=a^(b<<shift)
else:
mod=a
break
return (hex(div),hex(mod))
def poly_gcd(a=0x95,b=0x11b):
while(a!=0):
if(len(bin(a))-len(bin(b))>=0):
shift=len(bin(a))-len(bin(b))
a=a^(b<<shift)
else:
a,b=b,a
return hex(b)
def poly_extendedEuclid(a=0x95):
b=0x11b
if(b>a):
a,b=b,a
if(eval(poly_gcd(a,b))!=1):
print("!!!该多项式无乘法逆元.")
return -1
else:
x1,x2=1,0
y1,y2=0,1
r1,r2=a,b
while(r2!=0):
q=eval(poly_div(r1,r2)[0])
mod=eval(poly_div(r1,r2)[1])
x3=x1^eval(poly_multip(q,x2))
y3=y1^eval(poly_multip(q,y2))
r1,r2=r2,mod
x1,x2=x2,x3
y1,y2=y2,y3
return hex(y1)
#计算在GF(2^8)中的乘法逆元
#生成S盒
def SBox_Generate():
SBox=[0x00]
#初始化并求在有限域GF(2^8)中的逆
for i in range(1,16**2):
SBox.append(eval(poly_extendedEuclid(i)))
#初始化并求在有限域GF(2^8)中的逆
#字节Ci到位列向量
c=0x63
bin_c=[]
for i in range(8):
bin_c.append(c>>i&0x01)
#字节Ci到位列向量
bin_byte=[]
bin_newbyte=[]
newbyte=0
for i in range(16**2):
for j in range(8):
bin_byte.append(SBox[i]>>j&0x01)#字节到位列向量
#位列向量到字节
for k in range(8):
bin_newbyte.append((bin_byte[k]^bin_byte[(k+4)%8]^bin_byte[(k+5)%8]^bin_byte[(k+6)%8]^bin_byte[(k+7)%8]^bin_c[k]))
newbyte=newbyte+(bin_newbyte[k]*(2**k))
SBox[i]=newbyte
#位列向量到字节
bin_byte.clear()
bin_newbyte.clear()
newbyte=0
for i in range(16**2):
SBox[i]=hex(SBox[i])
return SBox
#生成S盒
#生成逆S盒
def Inverse_SBox_Generate():
ISBox=[0x00]
#初始化
for i in range(1,16**2):
ISBox.append(i)
#初始化
#字节Di到位列向量
d=0x05
bin_d=[]
for i in range(8):
bin_d.append(d>>i&0x01)
#字节Di到位列向量
bin_byte=[]
bin_newbyte=[]
newbyte=0
for i in range(16**2):
for j in range(8):
bin_byte.append(ISBox[i]>>j&0x01)#字节到位列向量
#位列向量到字节
for k in range(8):
bin_newbyte.append((bin_byte[(k+2)%8]^bin_byte[(k+5)%8]^bin_byte[(k+7)%8]^bin_d[k]))
newbyte=newbyte+(bin_newbyte[k]*(2**k))
ISBox[i]=newbyte
#位列向量到字节
bin_byte.clear()
bin_newbyte.clear()
newbyte=0
#求在有限域GF(2^8)中的逆
for i in range(16**2):
if(ISBox[i]==0x00):
ISBox[i]=0x00
continue
ISBox[i]=eval(poly_extendedEuclid(ISBox[i]))
#求在有限域GF(2^8)中的逆
for i in range(16**2):
ISBox[i]=hex(ISBox[i])
return ISBox
#生成逆S盒
SBox=SBox_Generate()
ISBox=Inverse_SBox_Generate()
def SubstituteBytes(initBytes="EA835CF00445332D655D98AD8596B0C5"):
#初始化输入
listInitBytes=[]
for i in range(0,len(initBytes),2):
listInitBytes.append("0x"+initBytes[i]+initBytes[i+1])
#初始化输入
for i in range(len(listInitBytes)):
listInitBytes[i]=SBox[eval(listInitBytes[i])]
Hex=""
for i in range(len(listInitBytes)):
if(len(listInitBytes[i][2:])==1):
Hex=Hex+"0"+listInitBytes[i][2:]
else:
Hex=Hex+listInitBytes[i][2:]
return(Hex)
def ISubstituteBytes(initBytes="87EC4A8CF26EC3D84D4C46959790E7A6"):
#初始化输入
listInitBytes=[]
for i in range(0,len(initBytes),2):
listInitBytes.append("0x"+initBytes[i]+initBytes[i+1])
#初始化输入
for i in range(len(listInitBytes)):
listInitBytes[i]=ISBox[eval(listInitBytes[i])]
Hex=""
for i in range(len(listInitBytes)):
if(len(listInitBytes[i][2:])==1):
Hex=Hex+"0"+listInitBytes[i][2:]
else:
Hex=Hex+listInitBytes[i][2:]
return(Hex)
def ShiftRows(Matrix="87EC4A8CF26EC3D84D4C46959790E7A6"):
listMatrix=[]
for i in range(0,len(Matrix),2):
listMatrix.append(eval("0x"+Matrix[i]+Matrix[i+1]))
#输入矩阵转置
Columns=[]
for i in range(0,16,4):
for j in range(4):
Columns.append(listMatrix[i//4+j*4])
#输入矩阵转置
for i in range(0,16,4):
ls_temp=[]
flag_temp=True
shift=i//4
for j in range(shift):
ls_temp.append(Columns[i+j])
for j in range(shift):
if(flag_temp):
for k in range(4-shift):
Columns[i+k]=Columns[i+k+shift]
flag_temp=False
Columns[i+4-shift+j]=ls_temp[j]
NewListMatrix=[]
#矩阵转置
NColumns=[]
for i in range(0,16,4):
for j in range(4):
NColumns.append(Columns[i//4+j*4])
#矩阵转置
for i in range(16):
NewListMatrix.append(hex(NColumns[i]))
#输出列表变换
roundMatrix=""
for i in range(len(NewListMatrix)):
if(len(NewListMatrix[i][2:])==1):
roundMatrix=roundMatrix+"0"+NewListMatrix[i][2:]
else:
roundMatrix=roundMatrix+NewListMatrix[i][2:]
#输出列表变换
return roundMatrix
def InverseShiftRows(IMatrix="876E46A6F24CE78C4D904AD897ECC395"):
listIMatrix=[]
for i in range(0,len(IMatrix),2):
listIMatrix.append(eval("0x"+IMatrix[i]+IMatrix[i+1]))
#输入矩阵转置
IColumns=[]
for i in range(0,16,4):
for j in range(4):
IColumns.append(listIMatrix[i//4+j*4])
#输入矩阵转置
for i in range(0,16,4):
ls_temp=[]
flag_temp=True
shift=i//4
for j in range(shift):
ls_temp.append(IColumns[i+4-j-1])
for j in range(shift):
if(flag_temp):
for k in range(4-shift):
IColumns[i+4-k-1]=IColumns[i+4-k-shift-1]
flag_temp=False
IColumns[i+j]=ls_temp[shift-j-1]
#矩阵转置
NIColumns=[]
for i in range(0,16,4):
for j in range(4):
NIColumns.append(IColumns[i//4+j*4])
#矩阵转置
NewListIMatrix=[]
for i in range(16):
NewListIMatrix.append(hex(NIColumns[i]))
#输出列表变换
roundMatrix=""
for i in range(len(NewListIMatrix)):
if(len(NewListIMatrix[i][2:])==1):
roundMatrix=roundMatrix+"0"+NewListIMatrix[i][2:]
else:
roundMatrix=roundMatrix+NewListIMatrix[i][2:]
#输出列表变换
return roundMatrix
#计算在GF(2^8)中的乘法
def GF2_8_poly_multip(a=0b01010111,b=0b10000011):
MiddleResult=[a]
mod=0x1B
result=0
for i in range(1,8):
temp_a=MiddleResult[i-1]<<1
if(MiddleResult[i-1]&0b10000000==0b10000000):
MiddleResult.append((temp_a^mod)&0b11111111)
else:
MiddleResult.append(temp_a)
for i in range(8):
if((b>>i)&0b00000001==0):
continue
else:
result=result^((b>>i)&0b00000001)*MiddleResult[i]
return hex(result)
#计算在GF(2^8)中的乘法
#列混淆
def MixColumns(Matrix="876E46A6F24CE78C4D904AD897ECC395"):
#初始化输入
listMatrix=[]
for i in range(0,len(Matrix),2):
listMatrix.append(eval("0x"+Matrix[i]+Matrix[i+1]))
#初始化输入
temp=0b00
MixMatrix=[0x02,0x03,0x01,0x01,0x01,0x02,0x03,0x01,0x01,0x01,0x02,0x03,0x03,0x01,0x01,0x02]
NewMatrix=[]
for k in range(0,16,4):
for i in range(4):
for j in range(4):
temp=temp^eval(GF2_8_poly_multip(listMatrix[i*4+j],MixMatrix[k+j]))
NewMatrix.append(temp)
temp=0b00
#矩阵转置
NColumns=[]
for i in range(0,16,4):
for j in range(4):
NColumns.append(NewMatrix[i//4+j*4])
#矩阵转置
for i in range(16):
NColumns[i]=hex(NColumns[i])
#输出列表变换
roundMatrix=""
for i in range(len(NColumns)):
if(len(NColumns[i][2:])==1):
roundMatrix=roundMatrix+"0"+NColumns[i][2:]
else:
roundMatrix=roundMatrix+NColumns[i][2:]
#输出列表变换
return roundMatrix
#列混淆
#逆向列混淆
def InverseMixColumns(IMatrix="473794ED40D4E4A5A3703AA64C9F42BC"):
#初始化输入
listIMatrix=[]
for i in range(0,len(IMatrix),2):
listIMatrix.append(eval("0x"+IMatrix[i]+IMatrix[i+1]))
#初始化输入
temp=0b00
InverseMixMatrix=[0x0E,0x0B,0x0D,0x09,0x09,0x0E,0x0B,0x0D,0x0D,0x09,0x0E,0x0B,0x0B,0x0D,0x09,0x0E]
NewMatrix=[]
for k in range(0,16,4):
for i in range(4):
for j in range(4):
temp=temp^eval(GF2_8_poly_multip(listIMatrix[i*4+j],InverseMixMatrix[k+j]))
NewMatrix.append(temp)
temp=0b00
#矩阵转置
NColumns=[]
for i in range(0,16,4):
for j in range(4):
NColumns.append(NewMatrix[i//4+j*4])
#矩阵转置
for i in range(16):
NColumns[i]=hex(NColumns[i])
#输出列表变换
roundMatrix=""
for i in range(len(NColumns)):
if(len(NColumns[i][2:])==1):
roundMatrix=roundMatrix+"0"+NColumns[i][2:]
else:
roundMatrix=roundMatrix+NColumns[i][2:]
#输出列表变换
return roundMatrix
#逆向列混淆
RC10=[0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36]#初始化轮常量
#双字循环
def doubleWordShift(eachRoundKey=[0xAF,0x7F,0x67,0x98]):
temp_DWord=eachRoundKey[0]
for Shift in range(3):
eachRoundKey[Shift]=eachRoundKey[Shift+1]
eachRoundKey[3]=temp_DWord
return(eachRoundKey)
#双字循环
#双字代替
def doubleWordSubstitute(eachRoundKey=[0x7F,0x67,0x98,0xAF]):
for i in range(4):
eachRoundKey[i]=eval(SBox[eachRoundKey[i]])
#双字代替
def KeyExtend(initKey="0F1571C947D9E8590CB7ADD6AF7F6798",Round=1):
#初始化输入
listInitKey=[]
for i in range(0,len(initKey),2):
listInitKey.append(eval("0x"+initKey[i]+initKey[i+1]))
#初始化输入
tempDWordKey=[]
for i in range(12,16):
tempDWordKey.append(listInitKey[i])
#g函数
doubleWordShift(tempDWordKey)
doubleWordSubstitute(tempDWordKey)
tempDWordKey[0]=tempDWordKey[0]^RC10[Round]
#g函数
for i in range(0,16,4):
for j in range(4):
listInitKey[i+j]=listInitKey[i+j]^tempDWordKey[j]
tempDWordKey[j]=listInitKey[i+j]
for i in range(len(listInitKey)):
listInitKey[i]=hex(listInitKey[i])
roundInitKey=""
for i in range(len(listInitKey)):
if(len(listInitKey[i][2:])==1):
roundInitKey=roundInitKey+"0"+listInitKey[i][2:]
else:
roundInitKey=roundInitKey+listInitKey[i][2:]
return(roundInitKey)
def KeyExtend_all(initKey="0F1571C947D9E8590CB7ADD6AF7F6798"):
allRoundKey=[initKey]
roundKey=initKey
for Round in range(1,11):
tempRoundKey=KeyExtend(roundKey,Round)
listInitKey=[]
for i in range(0,len(tempRoundKey),2):
listInitKey.append("0x"+tempRoundKey[i]+tempRoundKey[i+1])
roundKey=""
for i in range(len(listInitKey)):
if(len(listInitKey[i][2:])==1):
roundKey=roundKey+"0"+listInitKey[i][2:]
else:
roundKey=roundKey+listInitKey[i][2:]
allRoundKey.append(roundKey)
return(allRoundKey)
def encrypt(Plain="0123456789abcdeffedcba9876543210",key="0f1571c947d9e8590cb7add6af7f6798"):
roundKey=HexToListTranslation(key)
plainList=[]
keyList=[]
plainList=HexToListTranslation(Plain)
keyList=HexToListTranslation(key)
#初始化变换
cipherList=[]
for i in range(len(plainList)):
cipherList.append(hex(eval(plainList[i])^eval(keyList[i])))
#初始化变换
print("轮开始(第0轮):{}".format(Plain))
print("字节代替后:{}".format(""))
print("行移位后:{}".format(""))
print("列混淆后:{}".format(""))
print("轮密钥:{}".format(key))
for Round in range(1,11):
print("轮开始(第{}轮):{}".format(Round,ListToHexTranslation(cipherList)))
#字节代替
cipherList=HexToListTranslation(SubstituteBytes(ListToHexTranslation(cipherList)))
#字节代替
print("字节代替后:{}".format(ListToHexTranslation(cipherList)))
#行移位
cipherList=HexToListTranslation(ShiftRows(ListToHexTranslation(cipherList)))
#行移位
print("行移位后:{}".format(ListToHexTranslation(cipherList)))
#列混淆
if(Round<10):
cipherList=HexToListTranslation(MixColumns(ListToHexTranslation(cipherList)))
#列混淆
print("列混淆后:{}".format(ListToHexTranslation(cipherList)))
#轮密钥加
roundKey=HexToListTranslation(KeyExtend(ListToHexTranslation(roundKey),Round))
print("轮密钥:{}".format(ListToHexTranslation(roundKey)))
for i in range(len(cipherList)):
cipherList[i]=hex(eval(cipherList[i])^eval(roundKey[i]))
#轮密钥加
cipherList=ListToHexTranslation(cipherList)
print("-----------------加密结束-----------------:{}".format(cipherList))
return(cipherList)
def decrypt(Cipher="ff0b844a0853bf7c6934ab4364148fb9",key="0f1571c947d9e8590cb7add6af7f6798"):
roundKey_all=KeyExtend_all(key)
cipherList=[]
cipherList=HexToListTranslation(Cipher)
#初始化变换
plainList=[]
for i in range(len(cipherList)):
plainList.append(hex(eval(cipherList[i])^eval(HexToListTranslation(roundKey_all[10])[i])))
#初始化变换
print("轮开始(第10轮):{}".format(Cipher))
print("字节代替后:{}".format(""))
print("行移位后:{}".format(""))
print("轮密钥:{}".format(roundKey_all[len(roundKey_all)-1]))
for Round in range(9,-1,-1):
print("轮开始(第{}轮):{}".format(Round,ListToHexTranslation(plainList)))
#字节代替
plainList=HexToListTranslation(ISubstituteBytes(ListToHexTranslation(plainList)))
#字节代替
print("逆向字节代替后:{}".format(ListToHexTranslation(plainList)))
#行移位
plainList=HexToListTranslation(InverseShiftRows(ListToHexTranslation(plainList)))
#行移位
print("逆向行移位后:{}".format(ListToHexTranslation(plainList)))
#轮密钥加
for i in range(len(plainList)):
plainList[i]=hex(eval(plainList[i])^eval(HexToListTranslation(roundKey_all[Round])[i]))
#轮密钥加
print("轮密钥:{}".format((roundKey_all[Round])))
#列混淆
if(Round>0):
plainList=HexToListTranslation(InverseMixColumns(ListToHexTranslation(plainList)))
#列混淆
print("逆向列混淆后:{}".format(ListToHexTranslation(plainList)))
plainList=ListToHexTranslation(plainList)
print("-----------------解密结束-----------------:{}".format(plainList))
return(plainList)
def AES():
print("AES-128 encrypting(default arguments)......")
encrypt()
print("AES-128 decrypting(default arguments)......")
decrypt()
if __name__=="__main__":
AES()
测试结果