def _sm4_decrypt_128bits(self, message): ''' 单组128bits解密 ''' if len(message) != 32: raise Exception('原始分组数据长度错误,单个分组长度为128bits') if common.IsHexCharacter(message) == False: raise Exception('原始数据包含非法字符(非16进制字符)') X = [int(message[:8], 16), int(message[8:16], 16), int(message[16:24], 16), int(message[24:], 16)] for i in range(0, 32): xorrsp = common.Xor(common.Xor(common.Xor(X[i + 1], X[i + 2]), X[i + 3]), self.extkeys[31 - i]) X.append(common.Xor(X[i], _t_conv(xorrsp))) return '%08X%08X%08X%08X' % (X[35], X[34], X[33], X[32])
def _generate_ext_keys(initkey): ''' 通过密钥扩展算法生成加密算法的轮密钥 ''' if len(initkey) % 2 != 0: raise Exception('加密密钥长度[%s]错误' % len(initkey)) if common.IsHexCharacter(initkey) == False: raise Exception('加密密钥含有非法字符(非16进制字符)') MK = (initkey[:8], initkey[8:16], initkey[16:24], initkey[24:]) K = [] for i in range(0, len(MK)): K.append(common.Xor(int(MK[i], 16), SM4_FK[i])) for i in range(0, 32): xorrsp = common.Xor(common.Xor(common.Xor(K[i + 1], K[i + 2]), K[i + 3]), SM4_CK[i]) K.append(common.Xor(K[i], _tn_conv(xorrsp))) return K[4:]
def sm4_encrypt(self, message, enc_mode): ''' message 待加密数据 enc_mode 加密模式 ECB/CBC ''' if len(message) % 32 != 0: raise Exception('待加密数据长度[%s]错误,需要为32的整倍数(含填充数据)' % len(message)) if common.IsHexCharacter(message) == False: raise Exception('待加密数据含有非法字符(非16进制字符)') C = '' if enc_mode == SM4_ECB: position = 0 while True: ''' 循环加密所有分组 ''' group = message[position:position + 32] C += self._sm4_encrypt_128bits(group) position += 32 if len(message) == position: break elif enc_mode == SM4_CBC: position = 0 iv = CBC_IV while True: ''' 循环加密所有分组 ''' group = message[position:position + 32] xorrsp = common.Xor(int(iv, 16), int(group, 16)) iv = self._sm4_encrypt_128bits('%032X' % xorrsp) C += iv position += 32 if len(message) == position: break else: pass return C
def sm4_decrypt(self, message, dec_mode): ''' message 待解密密文数据 dec_mode 解密模式 ECB/CBC ''' if len(message) % 32 != 0: raise Exception('待解密数据长度[%s]错误,需要为32的整倍数' % len(message)) if common.IsHexCharacter(message) == False: raise Exception('待解密数据含有非法字符(非16进制字符)') M = '' if dec_mode == SM4_ECB: position = 0 while True: ''' 循环解密所有分组 ''' group = message[position:position + 32] M += self._sm4_decrypt_128bits(group) position += 32 if len(message) == position: break elif dec_mode == SM4_CBC: position = 0 iv = CBC_IV while True: ''' 循环解密所有分组 ''' group = message[position:position + 32] decrsp = self._sm4_decrypt_128bits(group) M += '%032X' % common.Xor(int(iv, 16), int(decrsp, 16)) position += 32 iv = group if len(message) == position: break else: pass return M
def sm4_decrypt(self, message, dec_mode): ''' message 待解密密文数据 dec_mode 解密模式 ECB/CBC ''' if len(message) % 32 != 0: raise Exception('待解密数据长度[%s]错误,需要为32的整倍数' % len(message)) if common.IsHexCharacter(message) == False: raise Exception('待解密数据含有非法字符(非16进制字符)') M = '' if dec_mode == SM4_ECB: position = 0 while True: ''' 循环解密所有分组 ''' group = message[position:position + 32] M += self._sm4_decrypt_128bits(group) position += 32 if len(message) == position: break elif dec_mode == SM4_CBC: position = 0 iv = CBC_IV while True: ''' 循环解密所有分组 ''' group = message[position:position + 32] decrsp = self._sm4_decrypt_128bits(group) M += '%032X' % common.Xor(int(iv, 16), int(decrsp, 16)) position += 32 iv = group if len(message) == position: break else: pass return M # ----------------------------------------------------------------------------------------------------- # 使用密钥'404142434445464748494A4B4C4D4E4F', # iv='21324354657687972132435465768797'," # data = 00000000000000000000000000000000 # # from common import * # import time # import logging # import gc # # # message = '00000000000000000000000000000000' # # print('待加密数据:'+message) # sm4 = SM4(key='404142434445464748494A4B4C4D4E4F') # C = sm4.sm4_encrypt(message_padding(message, SM4_PAD_UNION), SM4_CBC) # for j in range(5): # # t1 = time.time() # for i in range(10000): # sm4 = SM4(key='404142434445464748494A4B4C4D4E4F') # # print("C : "+ C ) # M = sm4.sm4_decrypt(C, SM4_CBC) # # print('M : '+ M) # t2 = time.time() # print(M) # print(t2-t1) # # # 测试时间 # # CBC设计加密解密一致 # # def func_en(i,p1,s1,PAD_MODE,en_mode): # tim1 = time.time() # sm4 = SM4(key='404142434445464748494A4B4C4D4E4F') # message = '00000000000000000000000000000000' # res= sm4.sm4_encrypt(message_padding(message,p1), s1) # tim2 = time.time() # test_time = tim2-tim1 # n = i+1 # logging.info("sm4算法'"+str(PAD_MODE)+'-'+ str(en_mode)+ ' 使用密钥404142434445464748494A4B4C4D4E4F,'+ # " 加密数据'00000000000000000000000000000000'," # + "加密得到数据"+str(res)+ " 加密第"+str(n)+"次消耗时间" + str(test_time) + "秒") # func_de(i,res,p1,s1,PAD_MODE,en_mode) # sm8 = None # gc.collect() # return res # # # 解密 # def func_de(i,res1,p1,s1,PAD_MODE,en_mode): # tim1 = time.time() # sm4 = SM4(key='404142434445464748494A4B4C4D4E4F') # res = sm4.sm4_decrypt(res1, s1) # tim2 = time.time() # test_time = tim2-tim1 # n = i+1 # logging.info("sm4算法'"+str(PAD_MODE)+'-'+ str(en_mode)+ '使用密钥404142434445464748494A4B4C4D4E4F'+" 解密数据,"+str(res1)+ "解密得到数据"+str(res)+ " 解密第"+str(n)+"次消耗时间" + str(test_time) + "秒") # sm8 = None # gc.collect() # return # for i in range(1000): # padmode= 'PAD_UNION ' # sm4mode= 'SM4_CBC' # p1 = SM4_PAD_UNION # s1 = SM4_CBC # logging.basicConfig(level=logging.DEBUG, # filename='./log-20191203-sm4-crypt-'+padmode+sm4mode+'-'+'.log', # filemode='a+', # format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # func_en(i,p1,s1,padmode,sm4mode) # # # 8EB0E22999E827CBF7E3ADF7D3EB92C1BECB5E2C0A0D15F655B5C3A6082B58C9 # 00000000000000000000000000000000 # 000000000000000000000000000000008 # 0000000000000000000000000000000 # 00000000000000000000000000000000 # 00000000000000000000000000000000