def verify_signature(accUsername, auth_sig_hash, auth_sig): dacom = BitShares(DACOM_NODE_WSS) account = dacom.rpc.get_account(accUsername) signature = unhexlify(auth_sig) pub = PublicKey(account['active']['key_auths'][0][0], 'FLO') vk = ecdsa.VerifyingKey.from_public_point(pub.point(), curve=ecdsa.SECP256k1) sig = bytes(signature)[1:] recoverParameter = (bytes(signature)[0]) - 4 - 27 digest = hashlib.sha256(auth_sig_hash).digest() # digest = hashlib.sha256(b'sdf').digest() p = _recover_public_key(digest, sig, recoverParameter) if p.to_der() != vk.to_der(): raise ValueError()
class Connection: def __init__(self, ip, port): self.stream = Buffer() self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((ip, port)) raw_pk = self.s.recv(33) self.pk = GraphenePublicKey(raw_pk.hex()) sk = PrivateKey() point = self.pk.point() * int.from_bytes(bytes(sk), "big") x: int = point.x() raw_data = x.to_bytes(32, "big") self.shared_secret = sha512(raw_data).digest() key = sha256(self.shared_secret).digest() crc = cityhash.CityHash128(self.shared_secret) data = crc.to_bytes(16, "little") iv = data[8:16] + data[:8] self.s.sendall(bytes.fromhex(repr(sk.pubkey))) self.encryptor = AES.new(key, AES.MODE_CBC, iv) self.test = AES.new(key, AES.MODE_CBC, iv) self.decryptor = AES.new(key, AES.MODE_CBC, iv) self.worker_thread = threading.Thread(target=self.worker) self.worker_thread.start() self.send( 5006, { "user_agent": "Haruka Mock Client", "core_protocol_version": 106, "inbound_address": "0.0.0.0", "inbound_port": 0, "outbound_port": 0, "node_public_key": sk.pubkey, "signed_shared_secret": ecdsa.sign_message(self.shared_secret, str(sk)), "chain_id": bytes.fromhex( "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" ), "user_data": { "platform": String("unknown") } }) def send(self, msg_type, data: dict): message_type = message_type_table[msg_type] message = message_type(data) res = message.pack() # for name, type_ in definition.items(): # res.extend(pack_field(data.get(name, None), type_)) length = len(res) if length % 16 != 8: pad_length = (8 - length % 16) if pad_length < 0: pad_length += 16 res += b"\x00" * pad_length res = pack("<II", length, msg_type) + res data = self.encryptor.encrypt(res) logging.debug("SEND >>> %s" % res) parse_message(res, None, 1) self.s.sendall(data) def worker(self): data = bytearray() while True: data.extend(self.s.recv(65535)) if len(data) % 16 == 0: msg = self.decryptor.decrypt(bytes(data)) else: continue data = bytearray() self.stream.write(msg) if len(msg) == 0: break logging.debug("RECV <<< %s" % msg) while self.stream.count(): size = unpack("<I", self.stream.peek(4))[0] expect = size + 8 + (16 - (size + 8) % 16) % 16 logging.debug("expect %s have %s" % (expect, self.stream.count())) if expect <= self.stream.count(): parse_message(self.stream.read(expect), self, 2) else: break