Python實現AES加解密

學習物聯網安全

老師讓Coding實現Aes加解密算法

百度發現大多數的算法恨麻煩,易讀性不強

看了兩眼就不想看

自己動手寫吧

'''
AES加密流程
一、前期準備
1、明文分組(例如128位明文32位一組,分爲4組)
2、明文轉換(轉換爲對應的十六進制)
二、加密流程
1、字節代換SusBytes():十六進制的高四位與低四位分別作爲行列座標輸入S盒,進行字節替換
2、行移位ShiftRows():第i行每個元素循環左移i位
3、列混合MixColumns():將行移位後的矩陣與固定的矩陣相乘
4、輪密鑰加變換AddRoundKey():將128位密鑰Ki與矩陣中的每個元素進行亦或操作
    其中Ki由密鑰擴展生成,密鑰擴展的方法:
    將128位原始密鑰輸入到一個4*4的狀態矩陣中W[j]="第j行"
    求Ki:if i%4 != 0:    W[i] = W[i-4] ^ W[i-1]
            else:   W[i] = W[i-4] T(W[i-1])
    其中求T(W[i]):
        W[i]中的元素循環左移一個字節
        對循環左移後的W[i]進行SusBytes()
        將前兩步的結果同輪常量Rcon[j]進行異或,其中j表示輪數

明文 + 輪密鑰加 + 10*(字節代換 + 行移位 + 列混合 + 輪密鑰加) -> 密文
第 i 輪 輪密鑰加 採用的密鑰爲 W[i*4 : i+3]
'''
S = [
    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, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
   	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
   	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
   	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
   	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
   	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
   	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
   	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
   	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
   	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
   	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
]
NS = [
    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
   	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
   	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
   	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
   	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
   	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
   	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
   	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
   	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
   	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
   	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
   	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
   	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
   	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
   	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
   	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
]
Rcon = [
    [0x01, 0x00, 0x00, 0x00],
    [0x02, 0x00, 0x00, 0x00],
    [0x04, 0x00, 0x00, 0x00],
    [0x08, 0x00, 0x00, 0x00],
    [0x01, 0x00, 0x00, 0x00],
    [0x02, 0x00, 0x00, 0x00],
    [0x04, 0x00, 0x00, 0x00],
    [0x08, 0x00, 0x00, 0x00],
    [0x1b, 0x00, 0x00, 0x00],
    [0x36, 0x00, 0x00, 0x00],
]
import numpy as np
#密鑰擴展
def Shiftnbytes(m, n, flag):#flag爲0:數組m左移n個字節,否則右移
    if flag == 0:
        for i in range(n):
            m.insert(len(m), m[0])
            m.remove(m[0])
    else:
        for i in range(n):
            m.insert(0, m.pop())
def T(w, i):#第 i 輪
    Shiftnbytes(w, 1, 0)#先左移一個字節
    SubBytes(w)#字節代換
    w = np.bitwise_not(w, Rcon[i])

def Get_Key(Key):
    '''
    Key 爲128位密鑰
    將密鑰轉換爲十組密鑰
    '''
    W = []#用以儲存擴展後的密鑰
    W.append(Key)#先將最初的四組密鑰添加進去
    for i in range(4, 10):
        if i % 4 != 0:
            W.append(np.bitwise_not(W[i-4], W[i-1]))
        else:
            W.append(np.bitwise_not(W[i-4], T(W[i-1], i)))
    return W

def AES_Init(Plaintext, Key):
    '''
    明文分組,明文轉換,將密鑰生成用於十次輪密鑰加的密鑰組
    '''
    Key = np.array(Key)#轉換位array類型
    Key = Key.reshape(4, 4)#轉換位4*4的數組
    Plaintext = np.array(Plaintext)
    Plaintext = Plaintext.reshape(4, 4)


#字節代換
def SubBytes(State_matrix, S):
    for dir, each in enumerate(State_matrix):
        left = each >> 4#高四位
        right = each << 4 >> 4#低四位
        State_matrix[dir] = S[left][right]

#行移位
def ShiftRows(State_matrix):
    for i in range(4):
        Shiftnbytes(State_matrix[i], i, 0)

#逆行移位
def NShiftRows(State_matrix):
    for i in range(4):
        Shiftnbytes(State_matrix[i], i, 1)

#列混合
def MixColumns(State_matrix):
    colM = [
        2, 3, 1, 1,
        1, 2, 3, 1,
        1, 1, 2, 3,
        3, 1, 1, 2
    ]
    State_matrix = np.dot(colM, State_matrix)

#逆列混合
def NMixColumns(State_matrix):
    colM = [
        2, 3, 1, 1,
        1, 2, 3, 1,
        1, 1, 2, 3,
        3, 1, 1, 2
    ]
    State_matrix = np.dot(State_matrix, colM)

def Round_key_plus(Res, W, i):#第 i 輪 輪密鑰加
    Res = np.bitwise_not(Res, W[i])
#加密
def AES_encryption(Plaintext, key):
    AES_Init(Plaintext, key)
    W = Get_Key(key)#輪密鑰之後的密鑰
    Round_key_plus(Plaintext, W, 0)
    for i in range(1, 9):
        SubBytes(Plaintext, S)
        ShiftRows(Plaintext)
        MixColumns(Plaintext)
        Round_key_plus(Plaintext, W, i)
    SubBytes(Plaintext, S)
    ShiftRows(Plaintext)
    Round_key_plus(Plaintext, W, 9)

    return Plaintext

#解密
def AES_Decrypt(Ciphertext, key):
    AES_Init(Ciphertext, key)
    W = Get_Key(key)  # 輪密鑰之後的密鑰
    Round_key_plus(Ciphertext, W, 0)
    for i in range(1, 9):
        SubBytes(Ciphertext, NS)
        NShiftRows(Ciphertext)
        NMixColumns(Ciphertext)
        Round_key_plus(Ciphertext, W, i)
    SubBytes(Ciphertext, NS)
    NShiftRows(Ciphertext)
    Round_key_plus(Ciphertext, W, 9)

    return Ciphertext
    

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章