def sign(self, message): ''' za = hashlib.sha256(b''.join( [self.entl, self.id, int_to_bytes(ECCPoint.a, 32), int_to_bytes(ECCPoint.b, 32), int_to_bytes(ECCPoint.xg, 32), int_to_bytes(ECCPoint.yg, 32), int_to_bytes(self.public.x, 32), int_to_bytes(self.public.y, 32)])).digest() ''' za = sm3.sm3_hash(list(b''.join( [self.entl, self.id, int_to_bytes(ECCPoint.a, 32), int_to_bytes(ECCPoint.b, 32), int_to_bytes(ECCPoint.xg, 32), int_to_bytes(ECCPoint.yg, 32), int_to_bytes(self.public.x, 32), int_to_bytes(self.public.y, 32)]))) za = int_to_bytes(int(za, 16), 32) m1 = b''.join([za, message]) #e = bytes_to_int(hashlib.sha256(m1).digest()) e = int(sm3.sm3_hash(list(m1)), 16) while True: #k = randint(1, ECCPoint.n - 1) k = 0x6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F temp = self.g.multi(k) r = (e + temp.x) % ECCPoint.n if r == 0 or r + k == ECCPoint.n: continue s = (ECCPoint.reverse(1 + self.private, ECCPoint.n) * (k - r * self.private)) % ECCPoint.n if s != 0: break return (int_to_bytes(r, 32), int_to_bytes(s, 32))
def authenticate(self, message, signature): r = bytes_to_int(signature[0]) s = bytes_to_int(signature[1]) if r < 1 or r >= ECCPoint.n or s < 1 or s >= ECCPoint.n: print("Authentication failed.") return 0 ''' za = hashlib.sha256(b''.join( [self.entl, self.id, int_to_bytes(ECCPoint.a, 32), int_to_bytes(ECCPoint.b, 32), int_to_bytes(ECCPoint.xg, 32), int_to_bytes(ECCPoint.yg, 32), int_to_bytes(self.public.x, 32), int_to_bytes(self.public.y, 32)])).digest() ''' za = sm3.sm3_hash(list(b''.join( [self.entl, self.id, int_to_bytes(ECCPoint.a, 32), int_to_bytes(ECCPoint.b, 32), int_to_bytes(ECCPoint.xg, 32), int_to_bytes(ECCPoint.yg, 32), int_to_bytes(self.public.x, 32), int_to_bytes(self.public.y, 32)]))) za = int_to_bytes(int(za, 16), 32) m1 = b''.join([za, message]) #e = bytes_to_int(hashlib.sha256(m1).digest()) e = int(sm3.sm3_hash(list(m1)), 16) t = (r + s) % ECCPoint.n if t == 0: print("Authentication failed.") return 0 temp = self.g.multi(s) + self.public.multi(t) R = (e + temp.x) % ECCPoint.n if R == r: #print("Authentication passed.") return 1 else: #print("Authentication failed.") return 0
def generate_session_key(idA, idB, Ra, Rb, D, x, master_public, entity, l): P1, P2, Ppub, g = master_public if entity == 'A': R = Rb elif entity == 'B': R = Ra else: raise Exception('Invalid entity') g1 = ate.pairing(R, D) g2 = g**x g3 = g1**x if (entity == 'B'): (g1, g2) = (g2, g1) uidA = sm3_hash(str2hexbytes(idA)) uidB = sm3_hash(str2hexbytes(idB)) kdf_input = uidA + uidB kdf_input += ec2sp(Ra) + ec2sp(Rb) kdf_input += fe2sp(g1) + fe2sp(g2) + fe2sp(g3) sk = sm3_kdf(kdf_input.encode('utf-8'), l) return sk
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 get_e(self, msg, pub, uid): entla = "0080" if int(uid, 16) == 0: uid = default_ida a = self.ecc_table["a"] b = self.ecc_table["b"] gx = self.ecc_table["g"][:64] gy = self.ecc_table["g"][64:] xa = pub[:32] ya = pub[32:] za = sm3.sm3_hash(list(bytes.fromhex(entla + uid + a + b + gx + gy + xa + ya))) return sm3.sm3_hash(list(bytes.fromhex(za + msg)))
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 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 kem_decap(master_public, identity, D, C1, l): if ec.is_on_curve(C1, ec.b2) == False: return FAILURE t = ate.pairing(C1, D) uid = sm3_hash(str2hexbytes(identity)) kdf_input = ec2sp(C1) + fe2sp(t) + uid k = sm3_kdf(kdf_input.encode('utf-8'), l) return k
def sign(master_public, Da, msg): g = master_public[3] rand_gen = SystemRandom() x = rand_gen.randrange(ec.curve_order) w = g**x msg_hash = sm3_hash(str2hexbytes(msg)) z = (msg_hash + fe2sp(w)).encode('utf-8') h = h2rf(2, z, ec.curve_order) l = (x - h) % ec.curve_order S = ec.multiply(Da, l) return (h, S)
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()
def public_key_extract(scheme, master_public, identity): P1, P2, Ppub, g = master_public user_id = sm3_hash(str2hexbytes(identity)) h1 = h2rf(1, (user_id + '01').encode('utf-8'), ec.curve_order) if (scheme == 'sign'): Q = ec.multiply(P2, h1) elif (scheme == 'keyagreement') | (scheme == 'encrypt'): Q = ec.multiply(P1, h1) else: raise Exception('Invalid scheme') Q = ec.add(Q, Ppub) return Q
def kem_encap(master_public, identity, l): P1, P2, Ppub, g = master_public Q = public_key_extract('encrypt', master_public, identity) rand_gen = SystemRandom() x = rand_gen.randrange(ec.curve_order) C1 = ec.multiply(Q, x) t = g**x uid = sm3_hash(str2hexbytes(identity)) kdf_input = ec2sp(C1) + fe2sp(t) + uid k = sm3_kdf(kdf_input.encode('utf-8'), l) return (k, C1)
def encrypt(self, data, pubkey): msg = data.hex() k = random_hex(self.para_len) C1 = self._kg(int(k, 16), self.ecc_table['g']) xy = self._kg(int(k, 16), pubkey) x2 = xy[0:self.para_len] y2 = xy[self.para_len:2 * self.para_len] ml = len(msg) t = sm3.sm3_kdf(xy.encode('utf8'), ml / 2) if int(t, 16) == 0: return None else: form = '%%0%dx' % ml C2 = form % (int(msg, 16) ^ int(t, 16)) C3 = sm3.sm3_hash( [i for i in bytes.fromhex('%s%s%s' % (x2, msg, y2))]) return bytes.fromhex('%s%s%s' % (C1, C3, C2))
def kem_dem_enc(master_public, identity, message, v): hex_msg = str2hexbytes(message) mbytes = len(hex_msg) mbits = mbytes * 8 k, C1 = kem_encap(master_public, identity, mbits + v) k = str2hexbytes(k) k1 = k[:mbytes] k2 = k[mbytes:] C2 = [] for i in range(mbytes): C2.append(hex_msg[i] ^ k1[i]) hash_input = C2 + k2 C3 = sm3_hash(hash_input)[:int(v / 8)] return (C1, C2, C3)
def private_key_extract(scheme, master_public, master_secret, identity): P1 = master_public[0] P2 = master_public[1] user_id = sm3_hash(str2hexbytes(identity)) m = h2rf(1, (user_id + '01').encode('utf-8'), ec.curve_order) m = master_secret + m if (m % ec.curve_order) == 0: return FAILURE m = master_secret * fq.prime_field_inv(m, ec.curve_order) if (scheme == 'sign'): Da = ec.multiply(P1, m) elif (scheme == 'keyagreement') | (scheme == 'encrypt'): Da = ec.multiply(P2, m) else: raise Exception('Invalid scheme') return Da
def decrypt(self, data, privKey): data = data.hex() len_2 = 2 * self.para_len len_3 = len_2 + 64 C1 = data[0:len_2] C3 = data[len_2:len_3] C2 = data[len_3:] xy = self._kg(privKey, C1) x2 = xy[0:self.para_len] y2 = xy[self.para_len:len_2] cl = len(C2) t = sm3.sm3_kdf(xy.encode('utf8'), cl / 2) if int(t, 16) == 0: return None else: form = '%%0%dx' % cl M = form % (int(C2, 16) ^ int(t, 16)) u = sm3.sm3_hash( [i for i in bytes.fromhex('%s%s%s' % (x2, M, y2))]) return bytes.fromhex(M)
def save_to_file(self, filename, password=None): content = {} key = self.keypair.private_key content["address"] = self.keypair.address content["encrypt"] = False if password is not None: crypt_sm4 = CryptSM4() password = self.pwd_ljust(password) crypt_sm4.set_key(bytes(password, "utf-8"), SM4_ENCRYPT) encrypt_value = crypt_sm4.crypt_cbc( self.cbc_iv, bytes(self.keypair.private_key, "utf-8")) key = str(base64.b64encode(encrypt_value), "utf-8") content["encrypt"] = True content["private_key"] = key content["type"] = "gm" # set mac of the password passwdBytes = bytes(password, "utf-8") content["mac"] = sm3.sm3_hash(passwdBytes) with open(filename, "w") as dump_f: json.dump(content, dump_f, indent=4) dump_f.close()
def load_from_file(self, filename, password=None): if password is None: return with open(filename, "r") as dump_f: content = json.load(dump_f) dump_f.close() if content["type"] != "gm": return # get and compare mac expected_mac = content["mac"] password = self.pwd_ljust(password) passwdBytes = bytes(password, "utf-8") mac = sm3.sm3_hash(passwdBytes) if not hmac.compare_digest(mac, expected_mac): raise ValueError("MAC mismatch") key = content["private_key"] crypt_sm4 = CryptSM4() crypt_sm4.set_key(bytes(password, "utf-8"), SM4_DECRYPT) key = base64.b64decode(bytes(key, "utf-8")) key = str(crypt_sm4.crypt_cbc(self.cbc_iv, key), "utf-8") self.from_key(key)
def verify(master_public, identity, msg, signature): (h, S) = signature if (h < 0) | (h >= ec.curve_order): return FAILURE if ec.is_on_curve(S, ec.b2) == False: return FAILURE Q = public_key_extract('sign', master_public, identity) g = master_public[3] u = ate.pairing(S, Q) t = g**h wprime = u * t msg_hash = sm3_hash(str2hexbytes(msg)) z = (msg_hash + fe2sp(wprime)).encode('utf-8') h2 = h2rf(2, z, ec.curve_order) if h != h2: return FAILURE return SUCCESS
def kem_dem_dec(master_public, identity, D, ct, v): C1, C2, C3 = ct mbytes = len(C2) l = mbytes * 8 + v k = kem_decap(master_public, identity, D, C1, l) k = str2hexbytes(k) k1 = k[:mbytes] k2 = k[mbytes:] hash_input = C2 + k2 C3prime = sm3_hash(hash_input)[:int(v / 8)] if C3 != C3prime: return FAILURE pt = [] for i in range(mbytes): pt.append(chr(C2[i] ^ k1[i])) message = ''.join(pt) return message
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)
for s in string: li.append(ord(s)) return li if __name__ == '__main__': #hash('test')==55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23 # strA='test' # strSecond = 'atta' strA = input('please input string to sm3:' ) #输入secret的值,后面计算中secret当做未知,仅知道其长度和hash值 strSecond = input('please input second part message:') #输入第二轮计算的字符串 length = len(strA) #计算secret的长度 y = sm3.sm3_hash(strToASCII(strA)) #计算secret的hash值用于修改二轮IV,存在y中 # print(y) #对hash(secret)进行分组,用于求二轮的IV,分组存在liNum中 liStr = [] liNum = [] count = 0 for i in range(0, len(y) + 1): if (count % 8 == 0 and count != 0): liStr.append('0x' + y[i - 8:i]) count = count + 1 for x in liStr: liNum.append(int(x, 16)) # print(count) # print(liStr) # print(liNum)
# 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))
from gmssl import sm3, func if __name__ == '__main__': y = sm3.sm3_hash(func.bytes_to_list(b"abc")) print(y)
# -*- coding: utf-8 -*- from gmssl import sm3, func if __name__ == '__main__': y = sm3.sm3_hash(func.str_to_list("abc")) print(y)
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):
for s in string: li.append(ord(s)) return li if __name__ == '__main__': # hash('test')==f2c01fe71e407f888399b0373c86576807dd07341d35f16194b58b07ee510a58 # strA='88888888' # strSecond='12341234' strA = input('please input string to sm3:' ) # 输入secret的值,后面计算中secret当做未知,仅知道其长度和hash值 strSecond = input('please input second part message:') # 输入第二轮计算的字符串 length = len(strA) # 计算secret长度 y = sm3.sm3_hash(str_to_ASCII(strA)) # 计算secret的hash值用于修改第二轮IV,存于y中 # 对hash(secret)进行分组,用于求二轮的IV,分组存在liNum中 liStr = [] liNum = [] count = 0 for i in range(0, len(y) + 1): if count % 8 == 0 and count != 0: liStr.append('0x' + y[i - 8:i]) count = count + 1 for x in liStr: liNum.append(int(x, 16)) strARandom = 'a' * length # 填充第一轮中的secret部分,长度相等即可 strPadding = '\x80' + '\x00' * (56 - length - 1) # 填充第一轮剩余部分 strLength = '\x00' * 6 # 第一轮数据长度前半部分
def hash_(m: bytes) -> bytes: return sm3.sm3_hash(func.bytes_to_list(m))
def create_hash(secret, message): return sm3.sm3_hash( func.bytes_to_list(bytes(secret + message, encoding='utf-8')))