用python实现aes ECB/CBC/CTR/CCM 的可执行文件

来源:互联网 发布:宇喜多秀家数据 编辑:程序博客网 时间:2024/06/06 11:40

aes ccm和gcm模式做个总结,加密库里没有这两种模式,时间比较紧,自己只写了ccm模式的函数,有需要的童孩拿去用,附件有个生成的exe

    

       if(len(a)>0):
            ccm_b0_flag_a = b"1"
        else:
            ccm_b0_flag_a = b"0"
        tes_a = arange(6)
#b0_flag
        ccm_b0_flag_data = (int(ccm_b0_flag_a)<<6) + (int((len(t)-2)/2)<<3) + int(14-len(n)) #bytes to int
 #       ccm_b0_flag_data_byte =  bytes(str(hex(int(ccm_b0_flag_data)), encoding='utf-8') #int to str to byte
        ccm_b0_flag_data_byte =  self.int2bytes(ccm_b0_flag_data) #int to str to byte
        ccm_b0.append(ccm_b0_flag_data_byte)
#b0_N        
        for i in range(len(n)):
            ccm_b0.append(self.int2bytes(n[i]))
#b0_Q      
        bytes_q = bytes(str(hex(len(p))),encoding='utf-8') # 0x(q_tmp) #int to str to byte
#       str_bytes_q = bytes_q.decode()  
        for i in range(0,16-len(ccm_b0)):
            ccm_b0.append(b'0x00')


        q_len = len(bytes_q[2:]) #剔除“0x ”这两个非数字的符号部分


#填充Q
        for i in range(len(bytes_q[2:])):
            ccm_b0[16-q_len+i]=self.int2bytes((bytes_q[i+2])-48) #由ascII 转换为 数字
#打印B0
        for i in range(ccm_b0.__len__()):
            print('ccm_b0 is ',(ccm_b0[i]))  #bytes to int 


##b1_A值 
        ccm_a_len_byte = bytes(str(hex(len(a))),encoding='utf-8') # 0x(q_tmp)
        if(len(a)<2**16-2**8):
            a_len_all_byte = 2
            for i in range(0,2):
                ccm_b1.append(b'0x00')
            
        elif(len(a)<2**32): # 6 bytes
            a_len_all_byte = 6
            ccm_b1.append(b'0xff')
            ccm_b1.append(b'0xfe')
            for i in range(0,4):
                ccm_b1.append(b'0x00')
        else: #10 bytes
            a_len_all_byte = 10
            ccm_b1.append(b'0xff')
            ccm_b1.append(b'0xff')
            for i in range(0,8):
                ccm_b1.append(b'0x00')
        a_len_byte = len(ccm_a_len_byte[2:])
        for i in range(0,len(ccm_a_len_byte[2:])):
            ccm_b1[a_len_all_byte-a_len_byte+i] = self.int2bytes((ccm_a_len_byte[2+i])-48)


        for i in range(0,len(a)):   #填A值
            ccm_b1.append(self.int2bytes(a[i]))
        
        while len(ccm_b1)%16:
            ccm_b1.append(b"0x00")   #长度A 16bytes对齐
#打印B0 
        for i in range(ccm_b1.__len__()):
            print('ccm_b1 is ',(ccm_b1[i]))  #bytes to int 
 
#C0_flag
        ccm_c0_flag_data = hex(14-len(n))
#        ccm_c0_flag_data_byte =  bytes(str(ccm_c0_flag_data), encoding='utf-8') #int to str to byte
        ccm_c0.append(ccm_c0_flag_data) #bytes to hex to list
#C0_N值
        for i in range(len(n)):
            ccm_c0.append(hex(n[i]))


#C0_cou(计数器值)
#        while len(ccm_c0)%16:
#            ccm_c0.append(hex(00))   #补0 ,16bytes对齐


        str_ccm_c = ""
        if(14-len(n) < 0x10):
            str_ccm_c = '0'
        for i in range(ccm_c0.__len__()):
            str_ccm_c0 = str(ccm_c0[i])
            str_ccm_c = str_ccm_c +str_ccm_c0[2:]
      
        while len(str_ccm_c)%32:
            str_ccm_c = str_ccm_c + '0'   #补0 ,16bytes对齐




# bytes to str    
#str(b, encoding = "utf-8")
#p填充开始16个bytes的 0 ,作为开始的aes_ccm_ctr 的block的输入
        str_ccm_p2 = ""
        str_ccm_in2 = ""
        for i in range(0,32):    #前面补齐16个0 ,作为开始的P ---S0 #填明文
            ccm_p2.append(hex(00))       #补0 ,16bytes对齐
        for i in range(0,len(p)):    #前面补齐16个0 ,作为开始的P ---S0 #填明文
            ccm_p2.append(hex(p[i]))       #补0 ,16bytes对齐
        for i in range(ccm_p2.__len__()):
            str_ccm_p2 = str(ccm_p2[i])
            str_ccm_in2 = str_ccm_in2 +str_ccm_p2[2:]
        while len(str_ccm_in2)%32:
            str_ccm_in2 = str_ccm_in2 + '0'   #补0 ,16bytes对齐
        bytes_ccm_p3 = bytes.fromhex(str_ccm_in2)


#ccm ctr的加/解密 
        ccm_key=bytes().fromhex(ccm_key2) #str to bytes  2b7e151628aed2a6abf7158809cf4f3c
        ctr_len_cnt=int((len(bytes_ccm_p3)+15)/16)


#CCM CTR


#        str_ccm_rlt = ""
        byte_ccm_rlt0 = []
        for i in range(0,ctr_len_cnt): # ctr iv / p  
#ccm ctr iv 
            str_ccm_c_tmp = str_ccm_c[:-len(str(i))] + str(i)
            bytes_ccm_c0 = bytes.fromhex(str_ccm_c_tmp)
            bytes_ccm_plaint = bytes_ccm_p3[0:16]
            if(len(bytes_ccm_p3)>16):
                bytes_ccm_p3 = bytes_ccm_p3[16:]


#ccm ctr plaintxt
            m_cypher_ctr = AES.new(ccm_key,AES.MODE_CTR,counter=lambda: bytes_ccm_c0) #解密时必须重新创建新的密文生成器
            ccm_ctr_slt = m_cypher_ctr.encrypt(bytes_ccm_plaint) #iv为 bytes类型


            if(i == 0):
                str_ccm_s0 = str(binascii.b2a_hex(ccm_ctr_slt))[2:-1]
            else:
#                str_ccm_rlt = str_ccm_rlt + str(binascii.b2a_hex(ccm_ctr_slt))[2:-1]
                byte_ccm_rlt0.append(binascii.b2a_hex(ccm_ctr_slt))
        
##b2_P值    
        print('byte_ccm_rlt0 len :',len(byte_ccm_rlt0))
        ccm_b2 = []
        if(ccm_enc_dec == 'encrypt'):
            ccm_plaintxt=p #加密前的输入是明文
        else:
            ccm_plaintxt=byte_ccm_rlt0[2:-1]  #解密后的结果是明文


        for i in range(0,len(ccm_plaintxt)):   #填明文
            ccm_b2.append(self.int2bytes(ccm_plaintxt[i]))
 
        while len(ccm_b2)%16:     #明文16bytes对齐
           ccm_b2.append(b"0x00")   
        


        for i in range(0,len(ccm_b1)):
            ccm_b0.append(ccm_b1[i])
        for i in range(0,len(ccm_b2)):
            ccm_b0.append(ccm_b2[i])




        str_ccm_cbc =""
        for i in range(0,len(ccm_b0)):
            str_ccm_b0_tmp = str(ccm_b0[i][2:])[2:-1] 
            if(len(str_ccm_b0_tmp)==1):
                str_ccm_b0_tmp = '0' + str_ccm_b0_tmp 
            str_ccm_cbc = str_ccm_cbc + str_ccm_b0_tmp
        bytes_ccm_cbc_in = bytes().fromhex(str_ccm_cbc)


#计算验证部分计算结果
        str_ccm_cbc_iv0 = "00"
        for i in range(0,15):
            str_ccm_cbc_iv0= str_ccm_cbc_iv0 + "00"
        bytes_ccm_cbc_iv0 = bytes().fromhex(str_ccm_cbc_iv0)




#ccm cbc
        m_cypher_cbc = AES.new(ccm_key,AES.MODE_CBC,bytes_ccm_cbc_iv0) #解密时必须重新创建新的密文生成器
        bytes_ccm_cbc_result = bytes_ccm_cbc_iv0 + m_cypher_cbc.encrypt(bytes_ccm_cbc_in) #iv为 bytes类型




##计算Tag
        bytes_ccm_cbc_tag_tmp = binascii.b2a_hex(bytes_ccm_cbc_result[len(bytes_ccm_cbc_result)-16:])
        str_ccm_cbc_tag22= str(bytes_ccm_cbc_tag_tmp)
        
        bytes_ccm_s0_tmp=bytes().fromhex(str_ccm_s0) 
        bytes_ccm_tag=bytes().fromhex(str_ccm_cbc_tag22[2:-1]) 
        bytes_ccm_tag_tmp2 = []


#0921


#        byte_ccm_rlt=bytes().fromhex(str_ccm_rlt) 
        for i in range(0,len(byte_ccm_rlt0)):
            bytes_ccm_tag_tmp2.append(byte_ccm_rlt0[i])
        print('byte_ccm_rlt0 :',byte_ccm_rlt0)
        print('byte_ccm_tag111:',bytes_ccm_tag_tmp2)


        for i in range(0,len(t)):
            ccm_tag = int(bytes_ccm_s0_tmp[i])^int(bytes_ccm_tag[i])
            bytes_ccm_tag_tmp2.append(self.int2bytes(ccm_tag))
        print('byte_ccm_tag :',bytes_ccm_tag_tmp2)
        return bytes_ccm_tag_tmp2



    if aes_mode=='ECB': #key 16B align ,plain 16bytes align

            mode=AES.MODE_ECB
            #=============== key ===============
            print (' 当前ECB数据为key :',key_str)   
            key2=self.func_align(key_str,16)
            
            key=bytes().fromhex(key2) #str to bytes
            #=============== plaintxt ===============
            print (' 当前ECB数据为plaintxt :',plaintxt_str)
            plaintxt2=self.func_align(plaintxt_str,16)            
            plaintxt=bytes().fromhex(plaintxt2) #str to bytes
            #enc_ecb
            if aes_enc_dec=='encrypt':
                m_cipher_ecb = AES.new(key,mode)              #密文生成器,MODE_ECB为加密模式
                encrypt_msg = m_cipher_ecb.encrypt(plaintxt)  #附加上iv值是为了在解密时找到在加密时用到的随机iv
                print ('ECB 加密 为:')
            elif aes_enc_dec=='decrypt':
                #dec_ecb
                d = AES.new(key,mode) #解密时必须重新创建新的密文生成器
                encrypt_msg = d.decrypt(plaintxt) #后十六位是真正的密文
            aes_txt_out.set(binascii.b2a_hex(encrypt_msg))
       
        elif aes_mode=='CBC': #key 16B align ,plain 16bytes align
            mode=AES.MODE_CBC


            print (' 当前CBC数据为key :',key_str)   
            key2=self.func_align(key_str,16)
            key=bytes().fromhex(key2) #str to bytes  2b7e151628aed2a6abf7158809cf4f3c
            
            print (' 当前CBC数据为iv :',iv_str)   
            iv1=self.func_align(iv_str,16)
            iv2=bytes().fromhex(iv1) #str to bytes  000102030405060708090a0b0c0d0e0f
            #=============== plaintxt ===============
            print (' 当前CBC数据为plaintxt :',plaintxt_str)
            plaintxt2=self.func_align(plaintxt_str,16)
            plaintxt=bytes().fromhex(plaintxt2) #str to bytes  6bc1bee22e409f96e93d7e117393172a
            
            #enc_cbc
            if aes_enc_dec=='encrypt':
               m_cypher_cbc = AES.new(key,mode,iv2) #解密时必须重新创建新的密文生成器
               encrypt_msg = iv2 + m_cypher_cbc.encrypt(plaintxt) #iv为 bytes类型
               print ('CBC加密后的值为:',binascii.b2a_hex(encrypt_msg[16:]))   #7649abac8119b246cee98e9b12e9197d
               
            elif aes_enc_dec=='decrypt':                
            #dec_cbc
                d = AES.new(key,mode,iv2) #解密时必须重新创建新的密文生成器
                encrypt_msg = d.decrypt(iv2 + plaintxt) #后十六位是真正的密文
                print ('CBC解密后的值为:',binascii.b2a_hex(encrypt_msg))
      #      Label(aes_tk, text=binascii.b2a_hex(encrypt_msg[16:]),bg='yellow',width=90,height=3).pack(side=TOP, expand=YES, fill=BOTH)          
            aes_txt_out.set(binascii.b2a_hex(encrypt_msg))
        elif aes_mode=='CTR':
            mode=AES.MODE_CTR
            
            print (' 当前CTR数据为key :',key_str)   
            key2=self.func_align(key_str,16)
            key=bytes().fromhex(key2) #str to bytes  2b7e151628aed2a6abf7158809cf4f3c
            
            print (' 当前CTR数据为counter :',iv_str)   
            iv1=self.func_align(iv_str,16)
            iv2=bytes().fromhex(iv1) #str to bytes  f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
          #  iv1=16*"i"
          #  iv2=iv1.encode(encoding="utf-8") #iv为 bytes类型,需str 2 bytes
            #=============== plaintxt ===============
            print (' 当前CTR数据为plaintxt :',plaintxt_str)
            plaintxt2=self.func_align(plaintxt_str,16)
            plaintxt=bytes().fromhex(plaintxt2) #str to bytes  6bc1bee22e409f96e93d7e117393172a
            
            #enc_ctr
            if aes_enc_dec=='encrypt':
                m_cypher_ctr = AES.new(key,mode,counter=lambda: iv2) 
                encrypt_msg = m_cypher_ctr.encrypt(plaintxt) #iv为 bytes类型
                print ('CTR加密后的值为:',binascii.b2a_hex(encrypt_msg))   #874d6191b620e3261bef6864990db6ce
     #           Label(aes_tk, text=binascii.b2a_hex(encrypt_msg),bg='yellow',width=90,height=3).pack(side=TOP, expand=YES, fill=BOTH)
            elif aes_enc_dec=='decrypt': 
            #dec_ctr
                d = AES.new(key,mode,counter=lambda: iv2) #解密时必须重新创建新的密文生成器
                encrypt_msg = d.decrypt(plaintxt)  
                print ('CTR解密后的值为:',encrypt_msg)
     #           Label(aes_tk, text=binascii.b2a_hex(encrypt_msg),bg='yellow',width=90,height=3).pack(side=TOP, expand=YES, fill=BOTH)
            aes_txt_out.set(binascii.b2a_hex(encrypt_msg))
        elif aes_mode=='CCM': #key 16B align ,plain 16bytes align
            encrypt_msg = self.aes_ccm(aes_enc_dec,iv_str,a_str,plaintxt_str,key_str,t_str)
            aes_txt_out.set(encrypt_msg)
        else:
            encrypt_msg="0123456789123456"
        
#        a_str.set(eval(a_str.get())) #chr(ascii) --字符 (ascii to 字符 ) #ord(字符) ----ascii 
#        a_str.set('aes_Entry_in2.get()')        
       
        self.init_data += 1
        print('cnt is %s!' % self.init_data)
原创粉丝点击