def encode(key,passwd): key = func.bytes_to_list(key) passwd = func.bytes_to_list(passwd) key_arr = [] raw_key = [] data_arr = [] for c in key: key_arr.append(c) raw_key.append(c) for c in passwd: data_arr.append(c) key = key_arr passwd = data_arr for i in range(len(passwd)): v5 = (key[(i + 2) & 7] * (key[(i & 7)] + key[(i + 1) & 7]) + key[(i + 3) & 7])&0xff passwd[i] ^= v5 ^ table[v5] key[(i & 7)] = (2 * v5 + 3)&0xff if (i & 0xf) == 0: key = sub_143A(raw_key,table[i&0xff]) out = b'' for i in passwd: out += i.to_bytes(1, byteorder='little') return out
def sm3_Len_Extension_Attack(msg,sec_len,oldhash,append_m): """ msg:原来的消息 sec_len:密钥长度 oldhash:原来的hash值 append_m:附加消息 """ new_secret = 'A' * secret_len #构造虚假消息 exmsg = my_padding(func.bytes_to_list(bytes(new_secret + msg.__str__(), encoding='utf-8'))) mid = round(len(exmsg) / 64) #原来的消息+padding的分组数 exmsg += func.bytes_to_list(bytes(append_m, encoding='utf-8')) exmsg = my_padding(exmsg) end = round(len(exmsg) / 64) #虚假消息的分组数 #只解出附加消息计算 B = [] for i in range(mid, end): B.append(exmsg[i * 64:(i + 1) * 64]) #将oldhash转化为附加消息的初始向量并重新计算hash值 V = [] v_mid = hash2v_mid(oldhash) V.append(v_mid) for i in range(0, end - mid): V.append(sm3.sm3_cf(V[i], B[i])) y = V[i + 1] result = "" for i in y: result = '%s%08x' % (result, i) return result
def crypt_cfb(input_data, crypt_mode): crypt_sm4 = CryptSM4() crypt_sm4.mode = crypt_mode i = 0 output_data = [] tmp = [0] * 16 iv_tmp = bytes_to_list(iv) if crypt_sm4.mode == SM4_ENCRYPT: crypt_sm4.set_key(iv_tmp, SM4_ENCRYPT) input_data = padding(bytes_to_list(input_data)) length = len(input_data) while length > 0: tmp[0:16] = crypt_sm4.one_round(crypt_sm4.sk, iv_tmp[0:16]) output_data += xor(tmp[0:16], input_data[i:i + 16]) iv_tmp = copy.deepcopy(output_data[i:i + 16]) i += 16 length -= 16 return list_to_bytes(output_data) else: crypt_sm4.set_key(iv_tmp, SM4_ENCRYPT) length = len(input_data) while length > 0: tmp[0:16] = crypt_sm4.one_round(crypt_sm4.sk, iv_tmp[0:16]) output_data += xor(tmp[0:16], input_data[i:i + 16]) iv_tmp = copy.deepcopy(input_data[i:i + 16]) i += 16 length -= 16 return unpadding(list_to_bytes(output_data))
def extension_attack(): message = b"abcde" msg_add = b"qwert" #正常对message+补位+msg_add进行散列 message1 = extension_message(func.bytes_to_list(message)) message_add = message1 + func.bytes_to_list(msg_add) hash_value1 = sm3.sm3_hash(message_add) ''' 先对message进行散列得到密文,然后将密文作为压缩函数的初始值对 message+补位+msg_add的第二个分组进行散列,所以只需要知 道message的散列值和长度,不需要知道message具体是啥,就能得到message+补位+msg_add 的散列值,实现了长度拓展攻击。 ''' y = sm3.sm3_hash(func.bytes_to_list(message)) IV = [] for i in range(0, 8): IV.append(int(y[i * 8:(i + 1) * 8], 16)) message2 = extension_message(message_add) y2 = sm3.sm3_cf(IV, message2[64:128]) hash_value2 = "" for i in y2: hash_value2 = '%s%08x' % (hash_value2, i) if hash_value1 == hash_value2: print("attack is ok!") print("hash_value is:", hash_value1)
def getpadding(secret_len, message): padding = func.bytes_to_list(bytes(message, encoding='utf-8')) padding.append(0x80) data_len = len(message) + secret_len for i in range(64 - 8 - 1 - data_len): padding.append(0x00) padding.extend( func.bytes_to_list(pack(">Q", (secret_len + len(message)) * 8))) # !!!! 注意这里要大端序标识secret + message的总的bit位数 # padding = "{zero}".format(zero = "\x00" * (64 - data_len - 1 - 8)) # print(type(pack(">Q", (secret_len+ len(message))*8))) # padding = str('\x80') + padding + str(pack(">Q", secret_len+ len(message))) return padding
def sm4_encrypt(m, k): crypt_sm4 = CryptSM4() crypt_sm4.set_key(k, 0) m = bytes_to_list(m) result = crypt_sm4.one_round(crypt_sm4.sk, m) result = list_to_bytes(result) return result
def sm2_enc(private_key, public_key, data): sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key) enc_data = sm2_crypt.encrypt(data) enc_data = func.bytes_to_list(enc_data) enc_data = [hex(i) for i in enc_data] print('encrypt_value:') print('/'.join(enc_data))
def sm3_hash_func(self): if self.plaintext_hex.text().strip() == "": self.Qmsgbox_show("Error", "Plaintext is null") return sm3_plaintext = bytes().fromhex(self.plaintext_hex.text().strip()) self.result_textEdit.append("Msg Hex: " + sm3_plaintext.hex().upper()) sm3_result = sm3.sm3_hash(func.bytes_to_list(sm3_plaintext)) self.sm3_hash.setText(sm3_result.upper()) self.result_textEdit.append("SM3 Hash Result: " + sm3_result.upper())
def publickey_to_address(self, publickey): publickeybytes = func.bytes_to_list(bytes(decode_hex(publickey))) hashres = sm3.sm3_hash( publickeybytes ) # sm3_hash 对应sm3_implement.py里的sm3_hash,返回的是hex形态的结果 hash_raw = decode_hex(hashres) # 转为bytes addr_raw = hash_raw[-20:] # 截取20个字节 addr = to_checksum_address(addr_raw) # 转为格式化的地址 return addr
def sm4_enc(value_s, key_s): crypt_sm4 = CryptSM4() iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' value = bytes(value_s, 'utf-8') key = bytes(key_s, 'utf-8') crypt_sm4.set_key(key, SM4_ENCRYPT) encrypt_value = crypt_sm4.crypt_cbc(iv, value) encrypt_value = func.bytes_to_list(encrypt_value) encrypt_value = [hex(i) for i in encrypt_value] return encrypt_value
def sm3_hash(*args): """ sm3杂凑 :param args: <bytes>字符串 :return: <bytes> """ temp = "" for i in args: temp = temp + str(i) m = sm3.sm3_hash(func.bytes_to_list(bytes(temp.encode()))) return bytes(m.encode())
def sm3_hash(msg): # print(msg) len1 = len(msg) # 引入随机虚构的消息,长度与msg相同 msg_new = func.bytes_to_list(b'a' * len1) len2 = len(msg_new) # 对msg、msg_new做补位操作 msg = plug(len1, msg) msg_new = plug(len2, msg_new) # test作为附加值 str_test = ['t', 'e', 's', 't'] for i in range(4): msg_new.append(ord(str_test[i])) msg.append(ord(str_test[i])) len1 = len(msg) len2 = len(msg_new) # msg、msg_new重新补位,加长度标识 msg = plug(len1, msg) msg_new = plug(len2, msg_new) group_count_new = round(len(msg_new) / 64) group_count = round(len(msg) / 64) B1 = [] for i in range(0, group_count): B1.append(msg[i * 64:(i + 1) * 64]) B2 = [] for i in range(0, group_count_new): B2.append(msg_new[i * 64:(i + 1) * 64]) V1 = [] V1.append(IV) for i in range(0, group_count): V1.append(sm3_cf(V1[i], B1[i])) V2 = [] V2.append(IV_new) # 将原明文求得的hash作为msg_new的链变量 V2.append(sm3_cf(V2[0], B2[1])) # msg_new取最后一个分组和V2链变量做一次压缩 y1 = V1[i + 1] y2 = V2[1] result1 = "" result2 = "" for i in y1: result1 = '%s%08x' % (result1, i) for i in y2: result2 = '%s%08x' % (result2, i) print("y1=" + result1) print("y2=" + result2) if result1 == result2: print("ATTACK SUCCESS!") else: print("ATTACK FAIL!")
def attackfunction(mess, realhashvalue, extension): #真实消息,真实哈希值,附加的消息 fakemess = padding(func.bytes_to_list(bytes(mess, encoding='utf-8'))) mid = round(len(fakemess) / 64) fakemess += func.bytes_to_list(bytes(extension, encoding='utf-8')) fakemess = padding(fakemess) end = round(len(fakemess) / 64) A = [] for i in range(mid, end): A.append(fakemess[i * 64:(i + 1) * 64]) # 把原来的哈希值在进行一次压缩函数的数学运算 B = [] hasham = hashasmess(realhashvalue) #把原来的哈希值在进行一次压缩函数的数学运算 B.append(hasham) for i in range(0, end - mid): B.append(sm3.sm3_cf(B[i], A[i])) y = B[i + 1] result = "" for i in y: result = '%s%08x' % (result, i) return result
def crypt_ctr(input_data, mode): crypt_sm4 = CryptSM4() i = 0 output_data = [] tmp = [0] * 16 ctr_tmp = ctr ctr_tmp_list = bytes_to_list(("%016x" % ctr_tmp).encode('ascii')) crypt_sm4.set_key(ctr_tmp_list, SM4_ENCRYPT) if mode == SM4_ENCRYPT: input_data = padding(bytes_to_list(input_data)) length = len(input_data) while length > 0: tmp[0:16] = crypt_sm4.one_round(crypt_sm4.sk, ctr_tmp_list[0:16]) output_data += xor(tmp[0:16], input_data[i:i + 16]) ctr_tmp += 1 ctr_tmp_list = bytes_to_list(("%016x" % ctr_tmp).encode('ascii')) i += 16 length -= 16 if mode == SM4_DECRYPT: return unpadding(list_to_bytes(output_data)) return list_to_bytes(output_data)
def save_file(file_path, file_path_save, pixel_data): img_src = Image.open(file_path) img_save = img_src.copy() pixel_data_list = bytes_to_list(pixel_data) for i in range(0, img_save.width): for j in range(0, img_save.height): pixel = list(img_save.getpixel((i, j))) for k in range(0, 4): pixel[k] = int(pixel_data_list[(i * img_save.height + j) * 4 + k]) img_save.putpixel((i, j), tuple(pixel)) img_save.save(file_path_save) img_save.close()
def generate_guess_hash(old_hash, secret_len, append_m): """ SM3长度扩展攻击 :param old_hash: secret的hash值 :param secret_len: secret的长度 :param append_m: 附加的消息 :return: hash(secret + padding + append_m) """ vectors = [] message = "" # 将old_hash分组,每组8个字节, 并转换为整数 for r in range(0, len(old_hash), 8): vectors.append(int(old_hash[r:r + 8], 16)) # 伪造消息 if secret_len > 64: for i in range(0, int(secret_len / 64) * 64): message += 'a' for i in range(0, secret_len % 64): message += 'a' message = func.bytes_to_list(bytes(message, encoding='utf-8')) message = padding(message) message.extend(func.bytes_to_list(bytes(append_m, encoding='utf-8'))) return my_sm3.sm3_hash(message, vectors)
def gen_signature(self, params=None): """生成签名信息 Args: params (object) 请求参数 Returns: 参数签名md5值 """ buff = "" for k in sorted(params.keys()): buff += str(k) + str(params[k]) buff += self.secret_key if "signatureMethod" in params.keys() and params["signatureMethod"] == "SM3": return sm3.sm3_hash(func.bytes_to_list(bytes(buff, encoding='utf8'))) else: return hashlib.md5(buff.encode("utf8")).hexdigest()
hasham = hashasmess(realhashvalue) #把原来的哈希值在进行一次压缩函数的数学运算 B.append(hasham) for i in range(0, end - mid): B.append(sm3.sm3_cf(B[i], A[i])) y = B[i + 1] result = "" for i in y: result = '%s%08x' % (result, i) return result #对消息进行填充 #将真实消息后按二进制填上1,16进制表现为0x80,最后在末尾填上消息长度 mess = "AAAAAAAA" hashvalue = sm3.sm3_hash(func.bytes_to_list(bytes(mess, encoding='utf-8'))) print('AAAAAAAA的哈希值:\n' + hashvalue) message_extension = 'BBBBB' #添加在填充消息之后的值 mess_padding = padding(func.bytes_to_list(bytes( mess, encoding='utf-8'))) + func.bytes_to_list( bytes(message_extension, encoding='utf-8')) messstr = str(func.list_to_bytes(mess_padding)) #for i in messstr: # print(i+" ",end="") #messstr.replace("0x00"," ") print('假消息: \n' + messstr) new_hashvalue = sm3.sm3_hash(mess_padding) #将填充后的消息哈希
def SM3(): data = binascii.unhexlify(params.get('dec_data')) digest = sm3.sm3_hash(func.bytes_to_list(data)) print(digest)
def hash_(m: bytes) -> bytes: return sm3.sm3_hash(func.bytes_to_list(m))
from gmssl import sm3, func if __name__ == '__main__': y = sm3.sm3_hash(func.bytes_to_list(b"abc")) print(y)
def hexdigest(self): return sm3.sm3_hash(func.bytes_to_list(self.text.encode()))
from gmssl import sm3, func x = input('input value to hash_sm3: ') x_b = bytes(x, encoding='utf-8') if __name__ == '__main__': y = sm3.sm3_hash(func.bytes_to_list(x_b)) print(y)
def create_hash(secret, message): return sm3.sm3_hash( func.bytes_to_list(bytes(secret + message, encoding='utf-8')))
def _multiarray_to_numpy(pytype, dtype, multiarray): dims = list(map(lambda x: x.size, multiarray.layout.dim)) if isinstance(multiarray.data,bytes): return np.array(func.bytes_to_list(multiarray.data), dtype=pytype).reshape(dims).astype(dtype) else: return np.array(multiarray.data, dtype=pytype).reshape(dims).astype(dtype)
# print(new_iv) return new_iv secret = 'sspku' #len(secret) = 5 message = 'hello,world' IV = create_hash(secret, message) append = 'attack' print("secret: " + secret) print("Input message: " + message + "\nInput append message: " + append) padding = getpadding(len(secret), message) print("padding: " + str(padding)) new_iv = get_new_iv(IV) print("NEW_IV = sm3(sercret + massage) = " + str(IV)) fake_data = func.bytes_to_list(bytes( "beida", encoding='utf-8')) # 已知secret长度为五位,这里随便用五位字符填充即可 fake_data.extend(padding) fake_data.extend(func.bytes_to_list(bytes(append, encoding='utf-8'))) new_data = func.bytes_to_list(bytes(secret, encoding='utf-8')) new_data.extend(padding) new_data.extend(func.bytes_to_list(bytes(append, encoding='utf-8'))) # print("input data", fake_data) print("sm3_hash(secret + message + padding + append) = " + str(sm3.sm3_hash(new_data))) print("my_hash(message + padding + append) = " + str(create_mysm3hash(fake_data, new_iv))) check_hash(sm3.sm3_hash(new_data), create_mysm3hash(fake_data, new_iv))
@Time:2019/10/12 @Author: hhzjj @Description:SM3长度扩展攻击 1.随机生成一个secret,算出secret的hash值 2.根据hash值推出第一次压缩之后各个寄存器里的值 3.在secret+padding之后附加一段消息,用上一步寄存器里的值作为IV去加密附加的那段消息,得到hash 4.用sm3去加密secret+padding+m',得到hash 5.第3步和第4步得到的hash值应该相等 """ from gmssl import sm3, func import random import my_sm3 import struct secret = str(random.random()) secret_hash = sm3.sm3_hash(func.bytes_to_list(bytes(secret, encoding='utf-8'))) secret_len = len(secret) append_m = "1901210403" # 附加消息 pad_str = "" pad = [] def generate_guess_hash(old_hash, secret_len, append_m): """ SM3长度扩展攻击 :param old_hash: secret的hash值 :param secret_len: secret的长度 :param append_m: 附加的消息 :return: hash(secret + padding + append_m) """ vectors = []
bit_length = len1 * 8 bit_length_str = [bit_length % 0x100] for i in range(7): bit_length = int(bit_length / 0x100) bit_length_str.append(bit_length % 0x100) for i in range(8): msg.append(bit_length_str[7 - i]) return msg #密钥 secret = '1901210741' secret_len = len(secret) msg = input('Enter you message:') old_hash = sm3.sm3_hash(func.bytes_to_list(bytes(secret + msg.__str__(),encoding='utf-8'))) print('hash of \''+msg+'\' : '+old_hash) #message want to add append_m = 'Length extension attack' new_msg_i = my_padding(func.bytes_to_list(bytes(secret + msg.__str__(),encoding='utf-8'))) \ + func.bytes_to_list(bytes(append_m,encoding='utf-8')) new_hash = sm3.sm3_hash(list(new_msg_i)) print('Create a deceptive message.(\'A*\'+msg+padding+m\')') print('Appended message is : ' + str(func.list_to_bytes(new_msg_i))) print('We guess its hash is : '+sm3_Len_Extension_Attack(msg,secret_len,old_hash,append_m)) print('And factually its hash is : '+new_hash) if new_hash == sm3_Len_Extension_Attack(msg,secret_len,old_hash,append_m):
from gmssl import sm3, func if __name__ == '__main__': y = sm3.sm3_hash(func.bytes_to_list(b"huangbao")) print(y)
def sm3_hash_str(self, msg): return sm3.sm3_hash(func.bytes_to_list(msg.encode()))