def testSignVerify(self): h = SHA1.new() h.update(b('blah blah blah')) class RNG(object): def __init__(self): self.asked = 0 def __call__(self, N): self.asked += N return Random.get_random_bytes(N) key = RSA.generate(1024) # Helper function to monitor what's request from MGF global mgfcalls def newMGF(seed,maskLen): global mgfcalls mgfcalls += 1 return bchr(0x00)*maskLen # Verify that PSS is friendly to all ciphers for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,RIPEMD160): h = hashmod.new() h.update(b('blah blah blah')) # Verify that sign() asks for as many random bytes # as the hash output size rng = RNG() signer = PKCS.new(key, randfunc=rng) s = signer.sign(h) signer.verify(h, s) self.assertEqual(rng.asked, h.digest_size) h = SHA1.new() h.update(b('blah blah blah')) # Verify that sign() uses a different salt length for sLen in (0,3,21): rng = RNG() signer = PKCS.new(key, saltLen=sLen, randfunc=rng) s = signer.sign(h) self.assertEqual(rng.asked, sLen) signer.verify(h, s) # Verify that sign() uses the custom MGF mgfcalls = 0 signer = PKCS.new(key, newMGF) s = signer.sign(h) self.assertEqual(mgfcalls, 1) signer.verify(h, s) # Verify that sign() does not call the RNG # when salt length is 0, even when a new MGF is provided key.asked = 0 mgfcalls = 0 signer = PKCS.new(key, newMGF, 0) s = signer.sign(h) self.assertEqual(key.asked,0) self.assertEqual(mgfcalls, 1) signer.verify(h, s)
def testSignVerify(self): h = SHA1.new() h.update(b('blah blah blah')) rng = Random.new().read key = MyKey(RSA.generate(1024,rng)) # Helper function to monitor what's request from MGF global mgfcalls def newMGF(seed,maskLen): global mgfcalls mgfcalls += 1 return bchr(0x00)*maskLen # Verify that PSS is friendly to all ciphers for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,RIPEMD160): h = hashmod.new() h.update(b('blah blah blah')) # Verify that sign() asks for as many random bytes # as the hash output size key.asked = 0 signer = PKCS.new(key) s = signer.sign(h) self.failUnless(signer.verify(h, s)) self.assertEqual(key.asked, h.digest_size) h = SHA1.new() h.update(b('blah blah blah')) # Verify that sign() uses a different salt length for sLen in (0,3,21): key.asked = 0 signer = PKCS.new(key, saltLen=sLen) s = signer.sign(h) self.assertEqual(key.asked, sLen) self.failUnless(signer.verify(h, s)) # Verify that sign() uses the custom MGF mgfcalls = 0 signer = PKCS.new(key, newMGF) s = signer.sign(h) self.assertEqual(mgfcalls, 1) self.failUnless(signer.verify(h, s)) # Verify that sign() does not call the RNG # when salt length is 0, even when a new MGF is provided key.asked = 0 mgfcalls = 0 signer = PKCS.new(key, newMGF, 0) s = signer.sign(h) self.assertEqual(key.asked,0) self.assertEqual(mgfcalls, 1) self.failUnless(signer.verify(h, s))
def generateQ(randfunc): S=randfunc(20) hash1=SHA1.new(S).digest() hash2=SHA1.new(long_to_bytes(bytes_to_long(S)+1)).digest() q = bignum(0) for i in range(0,20): c=bord(hash1[i])^bord(hash2[i]) if i==0: c=c | 128 if i==19: c= c | 1 q=q*256+c while (not isPrime(q)): q=q+2 if pow(2,159) < q < pow(2,160): return S, q raise RuntimeError('Bad q value generated')
def test_negative_unapproved_hashes(self): """Verify that unapproved hashes are rejected""" from Crypto.Hash import SHA1 self.description = "Unapproved hash (SHA-1) test" hash_obj = SHA1.new() signer = DSS.new(self.key_priv, 'fips-186-3') self.assertRaises(ValueError, signer.sign, hash_obj) self.assertRaises(ValueError, signer.verify, hash_obj, b("\x00") * 40)
def generate_py(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate a DSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ if bits<160: raise ValueError('Key length < 160 bits') obj=DSAobj() # Generate string S and prime q if progress_func: progress_func('p,q\n') while (1): S, obj.q = generateQ(randfunc) n=divmod(bits-1, 160)[0] C, N, V = 0, 2, {} b=(obj.q >> 5) & 15 powb=pow(bignum(2), b) powL1=pow(bignum(2), bits-1) while C<4096: for k in range(0, n+1): V[k]=bytes_to_long(SHA1.new(S+bstr(N)+bstr(k)).digest()) W=V[n] % powb for k in range(n-1, -1, -1): W=(W<<160)+V[k] X=W+powL1 p=X-(X%(2*obj.q)-1) if powL1<=p and isPrime(p): break C, N = C+1, N+n+1 if C<4096: break if progress_func: progress_func('4096 multiples failed\n') obj.p = p power=divmod(p-1, obj.q)[0] if progress_func: progress_func('h,g\n') while (1): h=bytes_to_long(randfunc(bits)) % (p-1) g=pow(h, power, p) if 1<h<p-1 and g>1: break obj.g=g if progress_func: progress_func('x,y\n') while (1): x=bytes_to_long(randfunc(20)) if 0 < x < obj.q: break obj.x, obj.y = x, pow(g, x, p) return obj
def runTest(self): key = RSA.generate(1024) hashed = SHA1.new(b("Test")) good_signature = PKCS1_PSS.new(key).sign(hashed) verifier = PKCS1_PSS.new(key.publickey()) self.assertEqual(verifier.verify(hashed, good_signature), True) # Flip a few bits in the signature bad_signature = strxor(good_signature, bchr(1) * len(good_signature)) self.assertEqual(verifier.verify(hashed, bad_signature), False)
def runTest(self): key = RSA.importKey(PKCS1_15_NoParams.rsakey) hashed = SHA1.new(b("Test")) good_signature = PKCS1_v1_5.new(key).sign(hashed) verifier = PKCS1_v1_5.new(key.publickey()) self.assertEqual(verifier.verify(hashed, good_signature), True) # Flip a few bits in the signature bad_signature = strxor(good_signature, bchr(1) * len(good_signature)) self.assertEqual(verifier.verify(hashed, bad_signature), False)
def test_asn1_encoding(self): """Verify ASN.1 encoding""" self.description = "ASN.1 encoding test" hash_obj = SHA1.new() signer = DSS.new(self.key_priv, 'fips-186-3', 'der') signature = signer.sign(hash_obj) # Verify that output looks like a SEQUENCE self.assertEqual(bord(signature[0]), 48) signer.verify(hash_obj, signature) # Verify that ASN.1 parsing fails as expected signature = bchr(7) + signature[1:] self.assertRaises(ValueError, signer.verify, hash_obj, signature)
def test_wrong_signature(self): key = RSA.generate(1024) msg_hash = SHA1.new(b("Message")) signer = PKCS.new(key) s = signer.sign(msg_hash) verifier = PKCS.new(key.publickey()) # The signature s should be OK verifier.verify(msg_hash, s) # Construct an incorrect signature and ensure that the check fails wrong_s = s[:-1] + bchr(bord(s[-1]) ^ 0xFF) self.assertRaises(ValueError, verifier.verify, msg_hash, wrong_s)
def test_streaming(self): """Verify that an arbitrary number of bytes can be encrypted/decrypted""" from Crypto.Hash import SHA1 segments = (1, 3, 5, 7, 11, 17, 23) total = sum(segments) pt = b("") while len(pt) < total: pt += SHA1.new(pt).digest() cipher1 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8) ct = cipher1.encrypt(pt) cipher2 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8) cipher3 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8) idx = 0 for segment in segments: self.assertEqual(cipher2.decrypt(ct[idx:idx+segment]), pt[idx:idx+segment]) self.assertEqual(cipher3.encrypt(pt[idx:idx+segment]), ct[idx:idx+segment]) idx += segment
def sign_bytes_dsa(byte_array, path_to_private_key_pem_file): # Use this method for DSA keys key = open(path_to_private_key_pem_file, 'r').read() # Import the key dsa_key = DSA.importKey(key) # Create a digest of nonce + cnonce # This only seems to work with SHA1 (SHA256 gives us a 401 error) buf = buffer(byte_array) digest = SHA1.new(buf).digest() # Digitally sign the digest with our private key # The corresponding public key is in our admin handle on the server k = random.StrongRandom().randint(1, dsa_key.q-1) sign = dsa_key.sign(digest, k) # Signature bytes from a DSA key need to be DER-encoded # This signature is in two parts (r and s) seq = DerSequence() seq.append(sign[0]) seq.append(sign[1]) return seq.encode()
async def hash_SHA1(data) -> str: if isinstance(data, str): hash_digest = SHA1.new(data=str.encode(data)) else: hash_digest = SHA1.new(data=data) return hash_digest.hexdigest()
def testVerify(self): verifier = PKCS.new(RSA.importKey(self.rsakey)) h = SHA1.new(self.msg) verifier.verify(h, t2b(self.signature))
def _sha1_new(*args): from Crypto.Hash import SHA1 _new_funcs['SHA1'] = _new_funcs['sha1'] = _new_funcs['SHA'] = _new_funcs[ 'sha'] = SHA1.new return SHA1.new(*args)
def getDigesto(self, texto): return SHA1.new(texto)
def runTest(self): verifier = pkcs1_15.new(RSA.importKey(self.rsakey)) hashed = SHA1.new(self.msg) verifier.verify(hashed, self.signature)
def main(): parser = argparse.ArgumentParser( description='Lenovo UEFI signing tool, (C) 2019 Stefan Schmidt') parser.add_argument('file', metavar='INPUT_FILE', nargs=1, help='input file') parser.add_argument('-o', '--output', dest='outfile', metavar='OUTPUT_FILE', required=True, help='signed output file') args = parser.parse_args() input_file = open(args.file[0], "rb") data = input_file.read() input_file.close() # Find public RSA key location in the input file pubkey_location = find_pubkey_location(data) # Extract the FFSv2 volume offset ffsv2_offset = find_first_ffsv2_volume_offset(data) # Get all TCPA blocks to update signature on each tcpa_volume_blocks = find_tcpa_volume_blocks(data) # Generate a new RSA key-pair print("INFO: Generating new 1024 bit key with 3 as public exponent...") key = RSA.generate(1024, e=3) for tcpa_volume_block in tcpa_volume_blocks: # Warning: We assume volume size and offset are still correct here, that may not be the case! tcpa_volume_offset = int.from_bytes(tcpa_volume_block[1][52:56], byteorder='little') tcpa_volume_size = int.from_bytes(tcpa_volume_block[1][56:62], byteorder='little') print("INFO: Volume offset: " + str(tcpa_volume_offset)) print("INFO: Volume size: " + str(tcpa_volume_size)) # Shift the offsets so that they're relative to the FFSv2 volume tcpa_volume_offset += ffsv2_offset # Calculate actual volume hash volume_data = data[tcpa_volume_offset:tcpa_volume_offset + tcpa_volume_size] volume_hash = SHA1.new(data=volume_data) # Insert calculated hash into TCPA volume block tcpa_volume_block[1] = tcpa_volume_block[1][:32] + volume_hash.digest( ) + tcpa_volume_block[1][32 + 20:] print("INFO: Volume hash updated") # Extract the block of data that is to be hashed for the signature block_to_hash = tcpa_volume_block[1][:tcpa_volume_block_length - 131] # Calculate SHA hash of the block tcpa_hash = SHA1.new(data=block_to_hash).digest() # Pad the block to the correct length for RSA padded_tcpa_hash = (b'\x00' * 108) + tcpa_hash # Calculate the signature sig = key._decrypt(int.from_bytes(padded_tcpa_hash, byteorder='big')) # Convert the raw signature number to a block of bytes signature_block = number.long_to_bytes( sig, number.ceil_div(number.size(key.n), 8)) print("INFO: Signature calculated") assert (len(signature_block) == 128) # Insert new signature into TCPA volume block tcpa_volume_block[1] = tcpa_volume_block[1][:tcpa_volume_block_length - 128] + signature_block # Insert modified block into data data = data[:tcpa_volume_block[0]] + tcpa_volume_block[1] + data[ tcpa_volume_block[0] + tcpa_volume_block_length:] print("INFO: TCPA volume block signed") # Signatures updated, now insert public key modulus_block = key.n.to_bytes(length=pubkey_modulus_length, byteorder='big') data = data[:pubkey_location] + modulus_block + data[ pubkey_location + pubkey_modulus_length:] print("INFO: Public key stored") # Write updated data output file output_file = open(args.outfile, "wb") output_file.write(data) output_file.close() print("\nIMAGE SIGNED!")
decipher = '' for letra in cipher: if letra in letras: index = letras.index(letra) - nro_casas decipher += letras[index] else: decipher += letra # Gravando texto decifrado decipher = decipher.lower() arq_json['decifrado'] = decipher print(arq_json['decifrado']) # Gravando hash SHA1 decipher = decipher.encode('utf-8') hashSHA1 = SHA1.new(decipher).hexdigest() arq_json['resumo_criptografico'] = hashSHA1 print(arq_json['resumo_criptografico']) print(arq_json) # Salvando arquivo resposta with open('answer.json', 'w', encoding='utf-8') as f: json.dump(obj=arq_json, fp=f, indent=4, sort_keys=False) f.close() # Submeter post do arquivo json resultante urlpost = 'https://api.codenation.dev/v1/challenge/dev-ps/submit-solution?token={0}'.format(s_token) file = {"answer": open("answer.json", "rb")} response = requests.post(urlpost, files=file) print(response.status_code) print(response.content)
alg = que[que.find('that'):que.find('(X)')][5:] last6 = que.strip()[-6:] print 'alg : {}, last6 : {}'.format(alg, last6) payload = 'CCTF' next_payload = '' while 1: if alg == 'sha512': h = SHA512.new() elif alg == 'sha224': h = SHA224.new() elif alg == 'sha384': h = SHA384.new() elif alg == 'sha1': h = SHA1.new() elif alg == 'md5': h = MD5.new() elif alg == 'sha256': h = SHA256.new() h.update(payload) next_payload = h.hexdigest() #print payload[-6:] if next_payload[-6:] == last6: break else: payload = next_payload print payload r.sendline(payload)
def __init__(self, Key=b'3DC5CA39'): self._CipherKey = SHA1.new(Key).digest() self._Cipher = Blowfish.new(self._CipherKey, Blowfish.MODE_ECB) self._IV = self._Cipher.encrypt(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')
def testSignVerify(self): h = SHA1.new() h.update(b('blah blah blah')) class RNG(object): def __init__(self): self.asked = 0 def __call__(self, N): self.asked += N return Random.get_random_bytes(N) key = RSA.generate(1024) # Helper function to monitor what's request from MGF global mgfcalls def newMGF(seed,maskLen): global mgfcalls mgfcalls += 1 return bchr(0x00)*maskLen # Verify that PSS is friendly to all hashes for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,RIPEMD160): h = hashmod.new() h.update(b('blah blah blah')) # Verify that sign() asks for as many random bytes # as the hash output size rng = RNG() signer = PKCS.new(key, randfunc=rng) s = signer.sign(h) signer.verify(h, s) self.assertEqual(rng.asked, h.digest_size) # Blake2b has variable digest size for digest_bits in (160, 256, 384): # 512 is too long hobj = BLAKE2b.new(digest_bits=digest_bits) hobj.update(b("BLAKE2b supports several digest sizes")) signer = PKCS.new(key) signature = signer.sign(hobj) signer.verify(hobj, signature) # Blake2s too for digest_bits in (128, 160, 224, 256): hobj = BLAKE2s.new(digest_bits=digest_bits) hobj.update(b("BLAKE2s supports several digest sizes")) signer = PKCS.new(key) signature = signer.sign(hobj) signer.verify(hobj, signature) h = SHA1.new() h.update(b('blah blah blah')) # Verify that sign() uses a different salt length for sLen in (0,3,21): rng = RNG() signer = PKCS.new(key, saltLen=sLen, randfunc=rng) s = signer.sign(h) self.assertEqual(rng.asked, sLen) signer.verify(h, s) # Verify that sign() uses the custom MGF mgfcalls = 0 signer = PKCS.new(key, newMGF) s = signer.sign(h) self.assertEqual(mgfcalls, 1) signer.verify(h, s) # Verify that sign() does not call the RNG # when salt length is 0, even when a new MGF is provided key.asked = 0 mgfcalls = 0 signer = PKCS.new(key, newMGF, 0) s = signer.sign(h) self.assertEqual(key.asked,0) self.assertEqual(mgfcalls, 1) signer.verify(h, s)
def gen_hash(self): h = SHA1.new() h.update(self.message.encode('utf8')) return h.hexdigest()
def XeCryptSha(*args: Union[bytes, bytearray]) -> bytes: hasher = SHA1.new() [hasher.update(x) for x in args] return hasher.digest()
def testVerify(self): verifier = PKCS.new(RSA.importKey(self.rsakey)) h = SHA1.new(self.msg) result = verifier.verify(h, t2b(self.signature)) self.failUnless(result)
from Crypto.Protocol.KDF import PBKDF2 from Crypto import Random from Crypto.Hash import SHA1 import time dictionary_file = "hash-dictionary.txt" target_hash = "d85e382c4a48731d850ec5956a20e5b3ccaa0e7d" file = open(dictionary_file, "r").read() texts = file.split("\n") start_time = time.time() for text in texts: utf8_text = text.encode("utf-8") hashed_text = SHA1.new(utf8_text).hexdigest() if hashed_text == target_hash: print("Dictionary: " + dictionary_file) print("Target: " + target_hash) print("Plain: " + text) break end_time = time.time() elapsed_time = end_time - start_time print("Time elapsed: " + str(elapsed_time))
def async_message_handler(self, message, isBinary): #_LOGGER.debug("async_message_handler") if isBinary: #_LOGGER.debug("RECV BINARY MESSAGE: {0} bytes".format(len(message))) if len(message) == 8 and message[0] == 3: #_LOGGER.debug('HEADER') self.message_header = MessageHeader(message) else: #_LOGGER.debug('BINARY DATA') self.message_body = MessageBody(message, True, self.message_header, self.config_data) else: #_LOGGER.debug("RECV TEXT MESSAGE: {0}".format(message)) if message.startswith("{"): self.message_body = MessageBody(message, False, self.message_header, self.config_data) else: self.message_body = MessageBody(self.decrypt_message(message), False, self.message_header, self.config_data) if "keyexchange" in self.message_body.control: _LOGGER.debug('PROCESS keyexchange response') command = "jdev/sys/getkey2/" + self.username _LOGGER.debug("SEND COMMAND: " + command) self.wsclient.send(self.encrypt_command(command)) elif "getkey2" in self.message_body.control: _LOGGER.debug('PROCESS getkey2 response') self.server_key = self.message_body.msg["LL"]["value"]["key"] #_LOGGER.debug(" server_key: {0} {1}".format(type(self.server_key), self.server_key)) self.server_salt = self.message_body.msg["LL"]["value"]["salt"] #_LOGGER.debug(" server_salt: {0} {1}".format(type(self.server_salt), self.server_salt)) #_LOGGER.debug(' Hash user password') hash_sha = SHA1.new() hash_sha.update( bytes('{0}:{1}'.format(self.password, self.server_salt), 'utf-8')) pwhash = hash_sha.hexdigest().upper() #_LOGGER.debug(' Hash credential') hash_hmac = HMAC.new(binascii.a2b_hex(self.server_key), digestmod=SHA1) hash_hmac.update( bytes('{0}:{1}'.format(self.username, pwhash), 'utf-8')) hash = hash_hmac.hexdigest() permissions = "4" uuid = "098802a2-02b4-603c-ffffeee000d80cfd" info = "LoxHome" command = "jdev/sys/gettoken/{0}/{1}/{2}/{3}/{4}".format( hash, self.username, permissions, uuid, info) _LOGGER.debug("SEND COMMAND: " + command) self.wsclient.send(self.encrypt_command(command)) elif "gettoken" in self.message_body.control: _LOGGER.debug('PROCESS gettoken response') command = "data/LoxAPP3.json" _LOGGER.debug("SEND COMMAND: " + command) self.wsclient.send(command) elif "LoxAPP3.json" in self.message_body.control: _LOGGER.debug('PROCESS LoxAPP3.json response') self.config_data = ConfigData(self.message_body.msg) command = "jdev/sps/enablebinstatusupdate" _LOGGER.debug("SEND COMMAND: " + command) self.ready.set() self.wsclient.send(self.encrypt_command(command)) elif "enablebinstatusupdate" in self.message_body.control: _LOGGER.debug('PROCESS enablebinstatusupdate response') elif "dev/sps/io/" in self.message_body.control: _LOGGER.debug('PROCESS io response') _LOGGER.debug("response: " + self.decrypt_message(message)) else: _LOGGER.debug('PROCESS <UNKNOWN> response') _LOGGER.debug("header: {0}-{1}-{2}".format( self.message_header.payload[0], self.message_header.payload[1], self.message_header.payload[2])) _LOGGER.debug("response: " + self.decrypt_message(message)) self.waiting_for_response = False
def sign(self, data): h = SHA1.new(data) signer = DSS.new(self.key, 'fips-186-3') return signer.sign(h)
obj2=AES.new(key, AES.MODE_CBC, newIV) decrypted=obj2.decrypt(newEncrypted) print("Decrypting bot response: ", decrypted.decode("UTF-8")) obj3=AES.new(key, AES.MODE_CBC, newIV) encrypted=obj3.encrypt(decrypted) return(encrypted, newIV) echoBot=Bot() attacker=MITM(echoBot) message=bytearray("testtesttesttest", "UTF-8") p=0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff g=2 a=random.randint(0, p-1) A=modexp(g, a, p) B=attacker.setPublic(p, g, A) s=bytearray(str(modexp(B, a, p)), "UTF-8") hashObj=SHA1.new() hashObj.update(s) key=hashObj.digest()[:16] iv=urandom(16) obj=AES.new(key, AES.MODE_CBC, iv) encrypted=obj.encrypt(message) (newEncrypted, newIV)=attacker.echo(encrypted, iv) obj2=AES.new(key, AES.MODE_CBC, newIV) decrypted=obj2.decrypt(newEncrypted)
def _sha1_new(*args): from Crypto.Hash import SHA1 _new_funcs['SHA1'] = _new_funcs['sha1'] = _new_funcs['SHA'] = _new_funcs['sha'] = SHA1.new return SHA1.new(*args)
def _connect(self) -> None: acc = Session.Accumulator() # Send ClientHello nonce = os.urandom(0x10) client_hello = Keyexchange.ClientHello( build_info=Version.standard_build_info(), cryptosuites_supported=[ Keyexchange.Cryptosuite.CRYPTO_SUITE_SHANNON ], login_crypto_hello=Keyexchange.LoginCryptoHelloUnion( diffie_hellman=Keyexchange.LoginCryptoDiffieHellmanHello( gc=self._keys.public_key_array(), server_keys_known=1), ), client_nonce=nonce, padding=bytes([0x1e])) client_hello_bytes = client_hello.SerializeToString() length = 2 + 4 + len(client_hello_bytes) self._conn.write_byte(0) self._conn.write_byte(4) self._conn.write_int(length) self._conn.write(client_hello_bytes) self._conn.flush() acc.write_byte(0) acc.write_byte(4) acc.write_int(length) acc.write(client_hello_bytes) # Read APResponseMessage length = self._conn.read_int() acc.write_int(length) buffer = self._conn.read(length - 4) acc.write(buffer) ap_response_message = Keyexchange.APResponseMessage() ap_response_message.ParseFromString(buffer) shared_key = Utils.to_byte_array( self._keys.compute_shared_key( ap_response_message.challenge.login_crypto_challenge. diffie_hellman.gs)) # Check gs_signature rsa = RSA.construct((int.from_bytes(self._serverKey, "big"), 65537)) pkcs1_v1_5 = PKCS1_v1_5.new(rsa) sha1 = SHA1.new() sha1.update(ap_response_message.challenge.login_crypto_challenge. diffie_hellman.gs) # noinspection PyTypeChecker if not pkcs1_v1_5.verify( sha1, ap_response_message.challenge.login_crypto_challenge. diffie_hellman.gs_signature): raise RuntimeError("Failed signature check!") # Solve challenge data = b"" for i in range(1, 6): # noinspection PyTypeChecker mac = HMAC.new(shared_key, digestmod=SHA1) mac.update(acc.array()) mac.update(bytes([i])) data += mac.digest() # noinspection PyTypeChecker mac = HMAC.new(data[:20], digestmod=SHA1) mac.update(acc.array()) challenge = mac.digest() client_response_plaintext = Keyexchange.ClientResponsePlaintext( login_crypto_response=Keyexchange.LoginCryptoResponseUnion( diffie_hellman=Keyexchange.LoginCryptoDiffieHellmanResponse( hmac=challenge)), pow_response=Keyexchange.PoWResponseUnion(), crypto_response=Keyexchange.CryptoResponseUnion()) client_response_plaintext_bytes = client_response_plaintext.SerializeToString( ) length = 4 + len(client_response_plaintext_bytes) self._conn.write_int(length) self._conn.write(client_response_plaintext_bytes) self._conn.flush() try: self._conn.set_timeout(1) scrap = self._conn.read(4) if 4 == len(scrap): length = (scrap[0] << 24) | (scrap[1] << 16) | ( scrap[2] << 8) | (scrap[3] & 0xff) payload = self._conn.read(length - 4) failed = Keyexchange.APResponseMessage() failed.ParseFromString(payload) raise RuntimeError(failed) except socket.timeout: pass finally: self._conn.set_timeout(0) with self._authLock: self._cipherPair = CipherPair(data[20:52], data[52:84]) self._authLockBool = True self._LOGGER.info("Connection successfully!")