def step1(self, pin): """First pairing step.""" context = SRPContext( 'Pair-Setup', str(pin), prime=constants.PRIME_3072, generator=constants.PRIME_3072_GEN, hash_func=hashlib.sha512) self._session = SRPClientSession( context, binascii.hexlify(self._auth_private).decode())
def step1(self, username, password): """First authentication step.""" self._check_initialized() context = AtvSRPContext( str(username), str(password), prime=constants.PRIME_2048, generator=constants.PRIME_2048_GEN) self.session = SRPClientSession( context, binascii.hexlify(self._auth_private).decode())
def get_private_and_public(ctx, username, password, private, preset): """Print out server public and private.""" session = SRPClientSession(SRPContext(username, password, prime=preset[0], generator=preset[1]), private=private) click.secho('Client private: %s' % session.private_b64) click.secho('Client public: %s' % session.public_b64)
def get_session_data(ctx, username, password, salt, server_public, private, preset): """Print out client session data.""" session = SRPClientSession(SRPContext(username, password, prime=preset[0], generator=preset[1]), private=private) session.process(server_public, salt, base64=True) click.secho('Client session key: %s' % session.key_b64) click.secho('Client session key proof: %s' % session.key_proof_b64) click.secho('Client session key hash: %s' % session.key_proof_hash_b64)
prime = srp_context.prime ##### # HERE WE ARE IN THE SERVER # client send the server user, password_verifier, salt, gen, prime server_context = SRPContext(username, prime=prime, generator=gen) ########### # authentication starts here server_session = SRPServerSession(server_context, password_verifier) server_public_B = server_session.public # to be sent to the client ##### # HERE WE ARE IN THE CLIENT client_session = SRPClientSession(srp_context) client_public_A = client_session.public # the client has received B # the server has received A ##### # HERE WE ARE IN THE SERVER server_session.process(client_public_A, salt) # generating the common secret server_key_proof = server_session.key_proof server_key_proof_hash = server_session.key_proof_hash print(server_key_proof) print(server_key_proof_hash) #####
M = input() # Process client public and verify session key proof. server_session.process(A, salt) print("expected M:", server_session.key_proof) assert server_session.verify_proof(M) # Server => Client: HAMK print("HAMK:", ensure_hash_size(server_session.key_proof_hash)) # Always keep the key secret! It is printed to validate the implementation. print("K:", ensure_hash_size(server_session.key)) if args.command == "client": client_session = SRPClientSession(context, private=args.private) print("a:", client_session.private) # Client => Server: username, A print("A:", client_session.public) # Server => Client: s, B sys.stdout.write("s: ") sys.stdout.flush() s = input() sys.stdout.write("B: ") sys.stdout.flush() B = input() client_session.process(B, s) # Client => Server: M
if __name__ == '__main__': server = remote(HOST, PORT) # domain parameters received_data = server.recv(DATA_SIZE).decode() server_data = json.loads(received_data) print(server_data['prime']) # prime print(server_data['generator']) # generator print(server_data['B']) # server public key B print(server_data['server_salt']) # salt # receive server verifier and salt and all the public parameters client_session = SRPClientSession( SRPContext(USERNAME, PASSWORD, prime=server_data['prime'], generator=server_data['generator'])) client_session.process(server_data['B'], server_data['server_salt']) client_public_A = client_session.public print(client_public_A) # client public key A client_session_key_proof = client_session.key_proof.hex() print(client_session_key_proof) client_parameters = json.dumps({ 'A': client_public_A, 'client_session_key_proof': client_session_key_proof })
def pairing(socket, config): msg = ProtocolMessage_pb2.ProtocolMessage() msg.type = ProtocolMessage_pb2.ProtocolMessage.CRYPTO_PAIRING_MESSAGE msg.Extensions[CryptoPairingMessage_pb2.cryptoPairingMessage].status = 0 msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData = tlv_build( { kTLVType_Method: b'\x00', kTLVType_State: b'\x01' }) msg.Extensions[CryptoPairingMessage_pb2.cryptoPairingMessage].state = 2 send(msg, socket) msg = receive(socket) parsed = tlv_parse(msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData) appletv_public = parsed[kTLVType_PublicKey] salt = parsed[kTLVType_Salt] code = input("Enter code displayed by Apple TV: ") session = SRPClientSession( SRPContext("Pair-Setup", code, PRIME_3072, PRIME_3072_GEN, hashlib.sha512, bits_random=256, bits_salt=128)) session.process(binascii.hexlify(appletv_public), binascii.hexlify(salt)) our_public = binascii.unhexlify(session.public) key_proof = binascii.unhexlify(session.key_proof) msg = ProtocolMessage_pb2.ProtocolMessage() msg.type = ProtocolMessage_pb2.ProtocolMessage.CRYPTO_PAIRING_MESSAGE msg.Extensions[CryptoPairingMessage_pb2.cryptoPairingMessage].status = 0 tlv = tlv_build({ kTLVType_State: b'\x03', kTLVType_PublicKey: our_public, kTLVType_Proof: key_proof }) msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData = tlv send(msg, socket) msg = receive(socket) parsed = tlv_parse(msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData) proof = parsed[kTLVType_Proof] if not session.verify_proof(binascii.hexlify(proof)): print("proof does not match!") exit(1) ltsk, ltpk = ed25519.create_keypair() hkdf = HKDF(hashes.SHA512(), 32, b"Pair-Setup-Controller-Sign-Salt", b"Pair-Setup-Controller-Sign-Info", default_backend()) x = hkdf.derive(binascii.unhexlify(session.key)) device_id = bytes(config['device_id'], 'utf-8') info = x + device_id + ltpk.to_bytes() subtlv = tlv_build({ kTLVType_Identifier: device_id, kTLVType_PublicKey: ltpk.to_bytes(), kTLVType_Signature: ltsk.sign(info) }) hkdf = HKDF(hashes.SHA512(), 32, b"Pair-Setup-Encrypt-Salt", b"Pair-Setup-Encrypt-Info", default_backend()) x = hkdf.derive(binascii.unhexlify(session.key)) cha_cha_poly = ChaCha20Poly1305(x) encrypted = cha_cha_poly.encrypt(b"\0\0\0\0PS-Msg05", subtlv, None) msg = ProtocolMessage_pb2.ProtocolMessage() msg.type = ProtocolMessage_pb2.ProtocolMessage.CRYPTO_PAIRING_MESSAGE msg.Extensions[CryptoPairingMessage_pb2.cryptoPairingMessage].status = 0 msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData = tlv_build( { kTLVType_State: b'\x05', kTLVType_EncryptedData: encrypted }) send(msg, socket) msg = receive(socket) parsed = tlv_parse(msg.Extensions[ CryptoPairingMessage_pb2.cryptoPairingMessage].pairingData) encrypted = parsed[kTLVType_EncryptedData] subtlv = tlv_parse( cha_cha_poly.decrypt(b"\0\0\0\0PS-Msg06", encrypted, None)) hkdf = HKDF(hashes.SHA512(), 32, b"Pair-Setup-Accessory-Sign-Salt", b"Pair-Setup-Accessory-Sign-Info", default_backend()) x = hkdf.derive(binascii.unhexlify(session.key)) info = x + subtlv[kTLVType_Identifier] + subtlv[kTLVType_PublicKey] ed25519.VerifyingKey(subtlv[kTLVType_PublicKey]).verify( subtlv[kTLVType_Signature], info) pickle.dump( { "seed": ltsk.to_seed(), "peer_id": subtlv[kTLVType_Identifier], "peer_public_key": subtlv[kTLVType_PublicKey] }, open("data/pairing.state", "wb"))
server = remote(HOST, PORT) auth_data = json.dumps({'username': username, 'prime': prime, 'generator': gen, 'password_verifier': password_verifier, 'salt': client_salt}) print(auth_data) server.send(auth_data.encode()) #receive server verifier and salt received_data = server.recv(DATA_SIZE).decode() server_data = json.loads(received_data) print(server_data) print("server public= "+str(server_data['server_verifier'])) # print("server salt = "+str(server_data['salt'])) #compute client parameters client_session = SRPClientSession(context) client_session.process(server_data['server_verifier'], client_salt) # Generate client public and session key proof. client_public = client_session.public print("client public = "+str(client_public)) client_session_key_proof = client_session.key_proof.hex() print("session key proof = " + str(client_session_key_proof)) print("session key proofB= " + str(client_session.key_proof)) client_parameters = json.dumps({'client_parameter': client_public, 'session_key_proof': client_session_key_proof}) server.send(client_parameters.encode()) print(client_session.key) # Generate session key proof hash