[关闭]
@Lin-- 2020-01-02T12:39:51.000000Z 字数 11148 阅读 289

ComSec作业8--Project:AES磁盘加密软件

ComSec


AES_S-Box and its inverse

  1. '''
  2. # File : AES_Box.py
  3. # Author : Hongpei Lin
  4. # Date : 20191111
  5. # Purpose : In algorithm AES
  6. # build S-Box in SubBytes
  7. '''
  8. #multilpy in GF(2^8)
  9. def mul(a,b):
  10. r=0
  11. while b:
  12. if b%2:
  13. r=r^a #add operation : XOR
  14. b=b>>1
  15. if a&int('10000000',2)==0: #first bit's value = 0
  16. a=a<<1
  17. else: #first bit's value = 1
  18. a=a<<1
  19. a=a^283
  20. return r
  21. #compute the max index number which < 2^count
  22. #return count, from 0
  23. def highest_bit(n):
  24. count = 0
  25. while n:
  26. count+=1
  27. n=n>>1
  28. return count-1
  29. #division about polymerization
  30. #return quotient and remainder
  31. def div(a,b):
  32. if a==b:
  33. return 1,0
  34. if a<b:
  35. return 0,a
  36. a_bit = highest_bit(a)
  37. b_bit = highest_bit(b)
  38. result = 0
  39. while not a_bit<b_bit:
  40. move=a_bit-b_bit
  41. temp=b<<move
  42. result=result+(1<<move)
  43. a=a^temp
  44. a_bit=highest_bit(a)
  45. return result,a
  46. #compute the inverse about a', where a*a'=1(mod m)
  47. #the algorithrm likes EGCD
  48. def inverse(a,m):
  49. r0,s0,r1,s1=1,0,0,1
  50. while m>0:
  51. t=m
  52. q,m=div(a,m)#q=a//m,m=a mod m
  53. a=t#a=m
  54. r0,r1=r1,r0^mul(q,r1)#sub operation:XOR
  55. s0,s1=s1,s0^mul(q,s1)
  56. return r0 #a'
  57. #build the matrix to multiply b0-b7 in step 3
  58. def build_T(T_value):
  59. T_List=[]
  60. for i in range(8):
  61. T_List.append(T_value)
  62. if T_value&1:
  63. T_value=(T_value>>1)^int('10000000',2)
  64. else:
  65. T_value=T_value>>1
  66. return T_List
  67. #compute every value's inverse in a matrix
  68. def S_inverse(S):
  69. for i in range(len(S)):
  70. for j in range(len(S[0])):
  71. S[i][j]=inverse(S[i][j],283)
  72. return S
  73. def build_byte_order_S(S):
  74. for i in range(len(S)):
  75. for j in range(len(S[0])):
  76. S[i][j]=(i<<4)+j
  77. return S
  78. def Compute_S_Box(T,S,c):
  79. for i in range(len(S)):
  80. for j in range(len(S[0])):
  81. # In order to multiply matrix T,let every bit in a byte reverse.
  82. Bit=list('{:08b}'.format(S[i][j]))
  83. Bit.reverse()
  84. Bit_s=""
  85. for k in Bit:
  86. Bit_s=Bit_s+str(k)
  87. Bit=int(Bit_s,2)
  88. # T */& b0-b7
  89. T_result=[]
  90. for l in T:
  91. And=l&Bit
  92. And_list=list('{:08b}'.format(And))
  93. And_reslut=int(And_list[0],2)
  94. for m in And_list[1:]:
  95. And_reslut=And_reslut^int(m,2)
  96. T_result.append(And_reslut)
  97. T_result_s=""
  98. for n in T_result:
  99. T_result_s=T_result_s+str(n)
  100. # get the reslut +/XOR c/63's reverse bits
  101. S_temp=int(T_result_s,2)^c
  102. S_temp=list('{:08b}'.format(S_temp))
  103. S_temp.reverse()#reverse again, get the final answer
  104. S_temp_s=""
  105. for o in S_temp:
  106. S_temp_s=S_temp_s+str(o)
  107. S[i][j]=int(S_temp_s,2)
  108. return S
  109. def SubByte(S_BOX,n):
  110. high_four=(n&int('11110000',2))>>4
  111. low_four=(n&int('00001111',2))
  112. return S_BOX[high_four][low_four]
  113. T=[]
  114. T_v=143
  115. T_vi=37
  116. c=int('11000110',2)
  117. ci=int('10100000',2)
  118. S1=[[0]*16 for i in range(16)]#S_Box
  119. Si=[[0]*16 for i in range(16)]#S_Box_Inverse
  120. #Generate S-Box
  121. S1=build_byte_order_S(S1)
  122. S1=S_inverse(S1)
  123. T=build_T(T_v)
  124. S1=Compute_S_Box(T,S1,c)
  125. #Generate Inverse S-Box
  126. Si=build_byte_order_S(Si)
  127. T=build_T(T_vi)
  128. Si=Compute_S_Box(T,Si,ci)
  129. Si=S_inverse(Si)
  130. '''
  131. #print the S-Box
  132. for i in range(16):
  133. for j in range(16):
  134. print(hex(Si[i][j])[2:],end=',')
  135. print("")
  136. '''

AES ShiftRow

  1. '''
  2. # File : AES_ShiftRow.py
  3. # Author : Hongpei Lin
  4. # Date : 20191111
  5. # Purpose : In algorithm AES (Step 2)
  6. '''
  7. def ShiftRow_Left_One(S):
  8. temp=S[0]
  9. for i in range(len(S)-1):
  10. S[i]=S[i+1]
  11. S[len(S)-1]=temp
  12. return S
  13. def ShiftRow_Left_All(S):
  14. for i in range(len(S)):
  15. for j in range(i):
  16. S[i]=ShiftRow_Left_One(S[i])
  17. return S
  18. '''
  19. Stest=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
  20. Stest=ShiftRow_Right_All(Stest)
  21. for i in range(len(Stest)):
  22. for j in range(len(Stest[0])):
  23. print(Stest[i][j],end=",")
  24. print("")
  25. '''

AES MixColunm

  1. '''
  2. # File : AES_MixColunm.py
  3. # Author : Hongpei Lin
  4. # Date : 20191113
  5. # Purpose : In algorithm AES (Step 3)
  6. '''
  7. import AES_Box
  8. Mixcolumn=[[2,3,1,1],
  9. [1,2,3,1],
  10. [1,1,2,3],
  11. [3,1,1,2]]
  12. #Multiply two matrix in GF(2^8)
  13. #matrix a and b have same rank, and thay are normal matrix, meaning row=colunm
  14. def Matrix_Mul(a,b):
  15. row=len(a)
  16. c=[[0,0,0,0] for i in range(4)]
  17. for i in range(row):
  18. for j in range(row):#row=colunm
  19. k=0
  20. while k<row:
  21. c[i][j]=c[i][j]^(AES_Box.mul(a[i][k],b[k][j]))
  22. k+=1
  23. return c
  24. '''
  25. examplem=[[int('87',16),int('f2',16),int('4d',16),int('97',16)],
  26. [int('6e', 16),int('4c',16),int('90',16),int('ec',16)],
  27. [int('46',16),int('e7',16),int('4a',16),int('c3',16)],
  28. [int('a6',16),int('8c',16),int('d8',16),int('95',16)]]
  29. test_mixcolunm=Matrix_Mul(Mixcolunm,examplem)
  30. for i in range(4):
  31. for j in range(4):
  32. print(hex(test_mixcolunm[i][j])[2:],end=',')
  33. print("")
  34. '''

AES RoundKey

AES Generate key and counter

  1. '''
  2. # File : AES_KeyAndCounter.py
  3. # Author : Hongpei Lin
  4. # Date : 20191113
  5. # Purpose : In algorithm AES (Step 4)
  6. '''
  7. import codecs
  8. import random
  9. def BuildRandomKey(n):
  10. number=str(random.randint(0,1))
  11. while n-1:
  12. number=number+str(random.randint(0,1))
  13. n=n-1
  14. return number
  15. #generate Key
  16. fk=codecs.open("Key.txt","w")
  17. fk.write(BuildRandomKey(128))
  18. fk.close()
  19. #generate counter
  20. fc=codecs.open("Counter.txt","w")
  21. fc.write(BuildRandomKey(128))
  22. fc.close()

AddRoundKey

  1. '''
  2. # File : AES_AddRoundKey.py
  3. # Author : Hongpei Lin
  4. # Date : 20191113
  5. # Purpose : In algorithm AES (Step 4)
  6. '''
  7. import codecs
  8. import AES_ShiftRow
  9. import AES_Box
  10. fo=codecs.open("Key.txt","r")
  11. KEY=fo.read()
  12. fo.close()
  13. #Zero round KEY,4*4 matrix,return string type
  14. key0=[[0,0,0,0] for i in range(4)]
  15. KEY_Index=0
  16. for i in range(len(key0)):
  17. for j in range(len(key0[0])):
  18. key0[i][j]=KEY[KEY_Index:KEY_Index+8]
  19. KEY_Index+=8
  20. RC=[1,2,4,8,16,32,64,128,int('1b',16),int('36',16)]
  21. #g function in AES step 4, w have 4 value,value's type is string(32 bits)
  22. #return string type(32 bits)
  23. def g_function(W,KeyRound):
  24. B=[]
  25. index=0
  26. while index<len(W):#4 times
  27. B.append(W[index:index+8])
  28. index+=8
  29. B=AES_ShiftRow.ShiftRow_Left_One(B)
  30. for i in range(len(B)):
  31. B[i]=AES_Box.SubByte(AES_Box.S1,int(B[i],2))#type=number
  32. B[0]=B[0]^RC[KeyRound]
  33. reslut=""
  34. for i in B:
  35. reslut+="{:08b}".format(i)
  36. return reslut#string type
  37. w=[0 for i in range(4)]#subkey
  38. #w0-w3,w is string type
  39. for i in range(len(key0)):
  40. temp=""
  41. for j in range(len(key0[0])):
  42. temp+=key0[j][i]
  43. w[i]=temp
  44. #Generate all the Key,output string type
  45. def build_subkey(W,KeyRoundTotal):
  46. time=0
  47. while time<KeyRoundTotal:
  48. Wg=g_function(W[-1],time)
  49. W_new=int(Wg,2)^int(W[len(W)-4],2)
  50. W_new=bin(W_new)[2:]
  51. while not len(W_new)==32:#高位填充
  52. W_new="0"+W_new
  53. W.append(W_new)
  54. for i in range(3):
  55. temp=int(W[-1],2)^int(W[len(W)-4],2)
  56. temp=bin(temp)[2:]
  57. while not len(temp)==32:
  58. temp="0"+temp
  59. W.append(temp)
  60. time+=1
  61. return W
  62. #w_test=['00001111000101010111000111001001','01000111110110011110100001011001','00001100101101111010110111010110','10101111011111110110011110011000']
  63. W_key=build_subkey(w,10)
  64. #input strings state and key, both are 128bits
  65. #output encripttext , string type, 128bits
  66. def AddRoundKey(state,key):
  67. state_matrix=[[0,0,0,0] for i in range(4)]
  68. key_matrix=[[0,0,0,0] for i in range(4)]
  69. result_matrix=[[0,0,0,0] for i in range(4)]
  70. result_string=""
  71. string_index=0
  72. for i in range(4):
  73. for j in range(4):
  74. #change srtring to number, to compute
  75. state_matrix[i][j]=int(state[string_index:string_index+8],2)
  76. key_matrix[i][j]=int(key[string_index:string_index+8],2)
  77. #XOR ,and change the reslut to string type,every value has 8 bits
  78. result_matrix[i][j]=key_matrix[i][j]^state_matrix[i][j]
  79. result_matrix[i][j]="{:08b}".format(result_matrix[i][j])
  80. result_string=result_string+result_matrix[i][j]
  81. string_index+=8
  82. return result_string
  83. '''
  84. for i in range(4):
  85. for j in range(4):
  86. print(W_key[i][j],end=',')
  87. print("")
  88. '''

AES CTR

  1. '''
  2. # File : AES_CTR.py
  3. # Author : Hongpei Lin
  4. # Date : 20191113
  5. # Purpose : AES CTR
  6. '''
  7. import codecs
  8. import AES_Box
  9. import AES_ShiftRow
  10. import AES_MixColumn
  11. import AES_AddRoundKey
  12. import random
  13. import re
  14. #make a string become bitstream
  15. def Str_to_Byte(s):
  16. news=""
  17. for i in s:
  18. news=news+"{:08b}".format(ord(i))
  19. return news
  20. #block the plaintext, every block have 128 bits
  21. #output list type, list's value is string(128 bits)
  22. #first value is stuffing bits counts.
  23. def Block_P(Plainfile):
  24. #read the file
  25. fo=codecs.open(Plainfile,"r",encoding='utf-8')
  26. Plaintext=fo.read()
  27. fo.close()
  28. Block=[]
  29. Plaintext=Str_to_Byte(Plaintext)
  30. PlainLength=len(Plaintext)
  31. #Byte stuffing counts, locat in lowest byte
  32. stufy_bit=128-PlainLength%128
  33. stufy_bit_str=AES_Box.SubByte(AES_Box.S1,stufy_bit)#use S-Box subbyte the number
  34. stufy_bit_str="{:08b}".format(stufy_bit_str)
  35. temp=""
  36. for i in range(120):
  37. temp=temp+str(random.randint(0,1))
  38. stufy_bit_str=temp+stufy_bit_str
  39. Block.append(stufy_bit_str)
  40. zero=""
  41. while stufy_bit:
  42. zero=zero+str(random.randint(0,1))
  43. stufy_bit-=1
  44. Plaintext=zero+Plaintext
  45. #stufy_bit=plaintext's index=0
  46. while stufy_bit<len(Plaintext):
  47. Block.append(Plaintext[stufy_bit:stufy_bit+128])
  48. stufy_bit+=128
  49. return Block
  50. #Counter is a 128 bits's string
  51. #output 128 bits string
  52. def CTR(Counter):
  53. # build state matrix,type is string
  54. state=[[0,0,0,0] for i in range(4)]
  55. Index=0
  56. for i in range(len(state)):
  57. for j in range(len(state[0])):
  58. state[i][j]=Counter[Index:Index+8]
  59. Index+=8
  60. #Step1:SubByte
  61. for i in range(len(state)):
  62. for j in range(len(state[0])):
  63. state[i][j]=AES_Box.SubByte(AES_Box.S1,int(state[i][j],2))#return int type
  64. state[i][j]='{:08b}'.format(state[i][j])
  65. #Step2:ShiftRow
  66. state=AES_ShiftRow.ShiftRow_Left_All(state)
  67. #Step3:MixColunm
  68. for i in range(len(state)):
  69. for j in range(len(state[0])):
  70. state[i][j]=int(state[i][j],2)
  71. state=AES_MixColumn.Matrix_Mul(AES_MixColumn.Mixcolumn,state)
  72. for i in range(len(state)):
  73. for j in range(len(state[0])):
  74. state[i][j]="{:08b}".format(state[i][j])
  75. #Step4:AddRoundKey,10 rounds
  76. counter_string=""
  77. #change matrix to string
  78. for i in range(len(state)):
  79. for j in range(len(state[0])):
  80. counter_string=counter_string+state[i][j]
  81. for i in range(10):
  82. Temp_Key=""
  83. for j in range(4):
  84. Temp_Key+=AES_AddRoundKey.W_key[(i+1)*4+j]
  85. counter_string=AES_AddRoundKey.AddRoundKey(counter_string,Temp_Key)#W_key from [4:44]
  86. return counter_string
  87. #Encrypt function,input filename
  88. def AES_Encrypt(filename,counter):
  89. Block_Text=Block_P(filename)
  90. C=[]#encrypttext,string type
  91. for i in Block_Text:
  92. C.append(int(i,2)^int(counter,2))
  93. counter=bin(int(counter,2)+1)[2:]
  94. #bit stuffing
  95. #every block text
  96. for i in range(len(C)):
  97. C[i]=bin(C[i])[2:]#string type
  98. zero=""
  99. stuffingLength=128-len(C[i])
  100. while stuffingLength:
  101. zero=zero+"0"
  102. stuffingLength-=1
  103. C[i]=zero+C[i]
  104. #encode
  105. writetext=""
  106. for i in C:
  107. s=re.findall(r".{8}",i)
  108. for j in s:
  109. writetext+=chr(int(j,2))
  110. #print(len(writetext[1:]))
  111. fw=codecs.open("AESEncryptText.txt","w",encoding='utf-8')
  112. fw.write(writetext)
  113. fw.close()
  114. return True
  115. #Decrypt function,input filename
  116. def AES_Decrypt(filename,counter):
  117. fr=codecs.open(filename,"r",encoding='utf-8')
  118. Block_Text=fr.read()
  119. fr.close()
  120. Block_bitstream=Str_to_Byte(Block_Text)
  121. P=[]
  122. Text_Index=0
  123. while Text_Index<len(Block_bitstream):
  124. P.append(Block_bitstream[Text_Index:Text_Index+128])
  125. Text_Index+=128
  126. #Decrypt
  127. for i in range(len(P)):
  128. P[i]=bin(int(counter,2)^int(P[i],2))[2:]
  129. counter = bin(int(counter, 2) + 1)[2:]
  130. for i in range(len(P)):
  131. stuffing_bit=128-len(P[i])
  132. zero=""
  133. while stuffing_bit:
  134. zero+="0"
  135. stuffing_bit-=1
  136. P[i]=zero+P[i]
  137. stufy_bit=AES_Box.SubByte(AES_Box.Si,int(P[0][-8:],2))# int type
  138. Plain_Stream=""
  139. for i in P[1:]:
  140. Plain_Stream=Plain_Stream+i
  141. Plain_Stream=Plain_Stream[stufy_bit:]#delete stuffing bits
  142. #change bitstream to string(code)
  143. Plain_Text=""
  144. s=re.findall(r".{8}",Plain_Stream)
  145. for j in s:
  146. Plain_Text+=chr(int(j, 2))
  147. fw=codecs.open("AESDecryptText.txt","w",encoding='utf-8')
  148. fw.write(Plain_Text)
  149. fw.close()
  150. return True

AES CMD Program

  1. '''
  2. # File : AES_CMD.py
  3. # Author : Hongpei Lin
  4. # Date : 20191119
  5. # Purpose : AES CMD program, running it in CMD view
  6. '''
  7. import sys
  8. import getopt
  9. import AES_CTR
  10. import codecs
  11. def __main__(argv):
  12. fcr = codecs.open("Counter.txt", "r", encoding='utf-8')
  13. counter = fcr.read()
  14. fcr.close()
  15. try:
  16. opts,args=getopt.getopt(argv,"he:d:",["help","encrypt=","decrypt="])
  17. except getopt.GetoptError:
  18. print("ERROR:AES_CMD.py -e <filename> \n or:AES_CMD.py -d <filename>")
  19. print(" or:AES_CMD.py --encrypt=<filename> \n or:AES_CMD.py --decrypt=<filename>")
  20. sys.exit(2)
  21. for opt,arg in opts:
  22. if opt in ("-h","--help"):
  23. print("Please input in these format")
  24. print("AES_CMD.py -e <filename>\nAES_CMD.py -d <filename>")
  25. print("AES_CMD.py --encrypt=<filename>\nAES_CMD.py --decrypt=<filename>")
  26. sys.exit()
  27. elif opt in ("-e","--encrypt"):
  28. counter=AES_CTR.CTR(counter)
  29. filename=arg
  30. if AES_CTR.AES_Encrypt(filename,counter):
  31. print("Encrypt Successfully! Wrote the CryptText in AESEncryptText.txt")
  32. elif opt in ("-d","--decrypt"):
  33. counter=AES_CTR.CTR(counter)
  34. filename=arg
  35. if AES_CTR.AES_Decrypt(filename,counter):
  36. print("Decrypt Successfully! Wrote the PlainText in AESDecryptText.txt")
  37. if __name__=="__main__":
  38. __main__(sys.argv[1:])
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注