コード例 #1
0
ファイル: server_auth.py プロジェクト: postlund/pyatv
def new_server_session(keys, pin):
    """Create SRP server session."""
    context = SRPContext(
        "Pair-Setup",
        str(pin),
        prime=constants.PRIME_3072,
        generator=constants.PRIME_3072_GEN,
        hash_func=hashlib.sha512,
        bits_salt=128,
        bits_random=512,
    )
    username, verifier, salt = context.get_user_data_triplet()

    context_server = SRPContext(
        username,
        prime=constants.PRIME_3072,
        generator=constants.PRIME_3072_GEN,
        hash_func=hashlib.sha512,
        bits_salt=128,
        bits_random=512,
    )

    session = SRPServerSession(
        context_server, verifier, binascii.hexlify(keys.auth).decode()
    )

    return session, salt
コード例 #2
0
ファイル: cli.py プロジェクト: mschwartz/pyatv-microservice
def get_user_data_triplet(username, password):
    """Print out user data triplet: username, password verifier, salt."""
    context = SRPContext(username, password)
    username, password_verifier, salt = context.get_user_data_triplet(
        base64=True)

    click.secho('Username: %s' % username)
    click.secho('Password verifier: %s' % password_verifier)
    click.secho('Salt: %s' % salt)
コード例 #3
0
 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())
コード例 #4
0
    def __init__(self, loop, credentials, atv_device_id):
        """Initialize a new instance of ProxyMrpAppleTV."""
        self.loop = loop
        self.credentials = credentials
        self.atv_device_id = atv_device_id
        self.server = None
        self.buffer = b''
        self.has_paired = False
        self.transport = None
        self.chacha = None
        self.connection = None
        self.input_key = None
        self.output_key = None
        self.mapping = {
            protobuf.DEVICE_INFO_MESSAGE: self.handle_device_info,
            protobuf.CRYPTO_PAIRING_MESSAGE: self.handle_crypto_pairing,
        }

        self._shared = None
        self._session_key = None
        self._signing_key = SigningKey(32 * b'\x01')
        self._auth_private = self._signing_key.to_seed()
        self._auth_public = self._signing_key.get_verifying_key().to_bytes()
        self._verify_private = curve25519.Private(secret=32 * b'\x01')
        self._verify_public = self._verify_private.get_public()

        self.context = SRPContext('Pair-Setup',
                                  str(1111),
                                  prime=constants.PRIME_3072,
                                  generator=constants.PRIME_3072_GEN,
                                  hash_func=hashlib.sha512,
                                  bits_salt=128)
        self.username, self.verifier, self.salt = \
            self.context.get_user_data_triplet()

        context_server = SRPContext('Pair-Setup',
                                    prime=constants.PRIME_3072,
                                    generator=constants.PRIME_3072_GEN,
                                    hash_func=hashlib.sha512,
                                    bits_salt=128)

        self._session = SRPServerSession(
            context_server, self.verifier,
            binascii.hexlify(self._auth_private).decode())
コード例 #5
0
ファイル: cli.py プロジェクト: mschwartz/pyatv-microservice
def get_private_and_public(username, password_verifier, private, preset):
    """Print out server public and private."""
    session = SRPServerSession(SRPContext(username,
                                          prime=preset[0],
                                          generator=preset[1]),
                               hex_from_b64(password_verifier),
                               private=private)

    click.secho('Server private: %s' % session.private_b64)
    click.secho('Server public: %s' % session.public_b64)
コード例 #6
0
ファイル: cli.py プロジェクト: mschwartz/pyatv-microservice
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)
コード例 #7
0
ファイル: cli.py プロジェクト: mschwartz/pyatv-microservice
def get_session_data(username, password_verifier, salt, client_public, private,
                     preset):
    """Print out server session data."""
    session = SRPServerSession(SRPContext(username,
                                          prime=preset[0],
                                          generator=preset[1]),
                               hex_from_b64(password_verifier),
                               private=private)

    session.process(client_public, salt, base64=True)

    click.secho('Server session key: %s' % session.key_b64)
    click.secho('Server session key proof: %s' % session.key_proof_b64)
    click.secho('Server session key hash: %s' % session.key_proof_hash_b64)
コード例 #8
0
ファイル: cli.py プロジェクト: mschwartz/pyatv-microservice
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)
コード例 #9
0
ファイル: test_context.py プロジェクト: xolian/srptools
def test_context_raises():
    context = SRPContext('alice')

    with pytest.raises(SRPException):
        context.get_common_password_hash(123)
コード例 #10
0
    s.bind((HOST, PORT))
except socket.error as msg:
    print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
    sys.exit()
print('Socket bind complete')

s.listen(10)
print('Socket now listening')

#wait to accept a connection - blocking call
while 1:
    conn, addr = s.accept()
    print('A new padding test requested by ' + addr[0] + ':' + str(addr[1]))

    #this should be done offline, only once, the server should store somewhere these data
    context = SRPContext(USERNAME, PASSWORD)
    username, password_verifier, server_salt = context.get_user_data_triplet()
    print(username)
    print(password_verifier)
    print(server_salt)

    prime = context.prime
    gen = context.generator
    print(prime)
    print(gen)

    # generate user-based server parameters
    server_session = SRPServerSession(
        SRPContext(username, prime=prime, generator=gen), password_verifier)
    server_public_B = server_session.public
    print(server_public_B)
コード例 #11
0
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
    })
    print(client_parameters)
コード例 #12
0
class ProxyMrpAppleTV(asyncio.Protocol):  # pylint: disable=too-many-instance-attributes  # noqa
    """Implementation of a fake MRP Apple TV."""
    def __init__(self, loop, credentials, atv_device_id):
        """Initialize a new instance of ProxyMrpAppleTV."""
        self.loop = loop
        self.credentials = credentials
        self.atv_device_id = atv_device_id
        self.server = None
        self.buffer = b''
        self.has_paired = False
        self.transport = None
        self.chacha = None
        self.connection = None
        self.input_key = None
        self.output_key = None
        self.mapping = {
            protobuf.DEVICE_INFO_MESSAGE: self.handle_device_info,
            protobuf.CRYPTO_PAIRING_MESSAGE: self.handle_crypto_pairing,
        }

        self._shared = None
        self._session_key = None
        self._signing_key = SigningKey(32 * b'\x01')
        self._auth_private = self._signing_key.to_seed()
        self._auth_public = self._signing_key.get_verifying_key().to_bytes()
        self._verify_private = curve25519.Private(secret=32 * b'\x01')
        self._verify_public = self._verify_private.get_public()

        self.context = SRPContext('Pair-Setup',
                                  str(1111),
                                  prime=constants.PRIME_3072,
                                  generator=constants.PRIME_3072_GEN,
                                  hash_func=hashlib.sha512,
                                  bits_salt=128)
        self.username, self.verifier, self.salt = \
            self.context.get_user_data_triplet()

        context_server = SRPContext('Pair-Setup',
                                    prime=constants.PRIME_3072,
                                    generator=constants.PRIME_3072_GEN,
                                    hash_func=hashlib.sha512,
                                    bits_salt=128)

        self._session = SRPServerSession(
            context_server, self.verifier,
            binascii.hexlify(self._auth_private).decode())

    def start(self, address, port):
        """Start the proxy instance."""
        # Establish connection to ATV
        self.connection = MrpConnection(address, port, self.loop)
        protocol = MrpProtocol(
            self.loop, self.connection, SRPAuthHandler(),
            MrpService(None, port, credentials=self.credentials))
        self.loop.run_until_complete(
            protocol.start(skip_initial_messages=True))
        self.connection.listener = self

        # Setup server used to publish a fake MRP server
        coro = self.loop.create_server(lambda: self, '0.0.0.0')
        self.server = self.loop.run_until_complete(coro)
        _LOGGER.info('Started MRP server at port %d', self.port)

    @property
    def port(self):
        """Port used by MRP proxy server."""
        return self.server.sockets[0].getsockname()[1]

    def connection_made(self, transport):
        """Client did connect to proxy."""
        self.transport = transport

    def _send(self, message):
        data = message.SerializeToString()
        _LOGGER.info('<<(DECRYPTED): %s', message)
        if self.chacha:
            data = self.chacha.encrypt(data)
            log_binary(_LOGGER, '<<(ENCRYPTED)', Message=message)

        length = variant.write_variant(len(data))
        self.transport.write(length + data)

    def _send_raw(self, raw):
        parsed = protobuf.ProtocolMessage()
        parsed.ParseFromString(raw)

        log_binary(_LOGGER, 'ATV->APP', Raw=raw)
        _LOGGER.info('ATV->APP Parsed: %s', parsed)
        if self.chacha:
            raw = self.chacha.encrypt(raw)
            log_binary(_LOGGER, 'ATV->APP', Encrypted=raw)

        length = variant.write_variant(len(raw))
        try:
            self.transport.write(length + raw)
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception('Failed to send to app')

    def message_received(self, _, raw):
        """Message received from ATV."""
        self._send_raw(raw)

    def data_received(self, data):
        """Message received from iOS app/client."""
        self.buffer += data

        while self.buffer:
            length, raw = variant.read_variant(self.buffer)
            if len(raw) < length:
                break

            data = raw[:length]
            self.buffer = raw[length:]
            if self.chacha:
                log_binary(_LOGGER, 'ENC Phone->ATV', Encrypted=data)
                data = self.chacha.decrypt(data)

            parsed = protobuf.ProtocolMessage()
            parsed.ParseFromString(data)
            _LOGGER.info('(DEC Phone->ATV): %s', parsed)

            try:

                def unhandled_message(_, raw):
                    self.connection.send_raw(raw)

                self.mapping.get(parsed.type, unhandled_message)(parsed, data)
            except Exception:  # pylint: disable=broad-except
                _LOGGER.exception('Error while dispatching message')

    def handle_device_info(self, message, _):
        """Handle received device information message."""
        _LOGGER.debug('Received device info message')

        # TODO: Consolidate this better with message.device_information(...)
        resp = messages.create(protobuf.DEVICE_INFO_MESSAGE)
        resp.identifier = message.identifier
        resp.inner().uniqueIdentifier = self.atv_device_id.decode()
        resp.inner().name = 'ATVProxy'
        resp.inner().systemBuildVersion = '15K600'
        resp.inner().applicationBundleIdentifier = 'com.apple.mediaremoted'
        resp.inner().protocolVersion = 1
        resp.inner().lastSupportedMessageType = 58
        resp.inner().supportsSystemPairing = True
        resp.inner().allowsPairing = True
        resp.inner().systemMediaApplication = "com.apple.TVMusic"
        resp.inner().supportsACL = True
        resp.inner().supportsSharedQueue = True
        resp.inner().supportsExtendedMotion = True
        resp.inner().sharedQueueVersion = 2
        self._send(resp)

    def handle_crypto_pairing(self, message, _):
        """Handle incoming crypto pairing message."""
        _LOGGER.debug('Received crypto pairing message')
        pairing_data = tlv8.read_tlv(message.inner().pairingData)
        seqno = pairing_data[tlv8.TLV_SEQ_NO][0]
        getattr(self, "_seqno_" + str(seqno))(pairing_data)

    def _seqno_1(self, pairing_data):
        if self.has_paired:
            server_pub_key = self._verify_public.serialize()
            client_pub_key = pairing_data[tlv8.TLV_PUBLIC_KEY]

            self._shared = self._verify_private.get_shared_key(
                curve25519.Public(client_pub_key), hashfunc=lambda x: x)

            session_key = hkdf_expand('Pair-Verify-Encrypt-Salt',
                                      'Pair-Verify-Encrypt-Info', self._shared)

            info = server_pub_key + self.atv_device_id + client_pub_key
            signature = SigningKey(self._signing_key.to_seed()).sign(info)

            tlv = tlv8.write_tlv({
                tlv8.TLV_IDENTIFIER: self.atv_device_id,
                tlv8.TLV_SIGNATURE: signature
            })

            chacha = chacha20.Chacha20Cipher(session_key, session_key)
            encrypted = chacha.encrypt(tlv, nounce='PV-Msg02'.encode())

            msg = messages.crypto_pairing({
                tlv8.TLV_SEQ_NO: b'\x02',
                tlv8.TLV_PUBLIC_KEY: server_pub_key,
                tlv8.TLV_ENCRYPTED_DATA: encrypted
            })

            self.output_key = hkdf_expand('MediaRemote-Salt',
                                          'MediaRemote-Write-Encryption-Key',
                                          self._shared)

            self.input_key = hkdf_expand('MediaRemote-Salt',
                                         'MediaRemote-Read-Encryption-Key',
                                         self._shared)

            log_binary(_LOGGER,
                       'Keys',
                       Output=self.output_key,
                       Input=self.input_key)

        else:
            msg = messages.crypto_pairing({
                tlv8.TLV_SALT:
                binascii.unhexlify(self.salt),
                tlv8.TLV_PUBLIC_KEY:
                binascii.unhexlify(self._session.public),
                tlv8.TLV_SEQ_NO:
                b'\x02'
            })

        self._send(msg)

    def _seqno_3(self, pairing_data):
        if self.has_paired:
            self._send(messages.crypto_pairing({tlv8.TLV_SEQ_NO: b'\x04'}))
            self.chacha = chacha20.Chacha20Cipher(self.input_key,
                                                  self.output_key)
        else:
            pubkey = binascii.hexlify(
                pairing_data[tlv8.TLV_PUBLIC_KEY]).decode()
            self._session.process(pubkey, self.salt)

            proof = binascii.unhexlify(self._session.key_proof_hash)
            assert self._session.verify_proof(
                binascii.hexlify(pairing_data[tlv8.TLV_PROOF]))

            msg = messages.crypto_pairing({
                tlv8.TLV_PROOF: proof,
                tlv8.TLV_SEQ_NO: b'\x04'
            })
            self._send(msg)

    def _seqno_5(self, _):
        self._session_key = hkdf_expand('Pair-Setup-Encrypt-Salt',
                                        'Pair-Setup-Encrypt-Info',
                                        binascii.unhexlify(self._session.key))

        acc_device_x = hkdf_expand('Pair-Setup-Accessory-Sign-Salt',
                                   'Pair-Setup-Accessory-Sign-Info',
                                   binascii.unhexlify(self._session.key))

        device_info = acc_device_x + self.atv_device_id + self._auth_public
        signature = self._signing_key.sign(device_info)

        tlv = tlv8.write_tlv({
            tlv8.TLV_IDENTIFIER: self.atv_device_id,
            tlv8.TLV_PUBLIC_KEY: self._auth_public,
            tlv8.TLV_SIGNATURE: signature
        })

        chacha = chacha20.Chacha20Cipher(self._session_key, self._session_key)
        encrypted = chacha.encrypt(tlv, nounce='PS-Msg06'.encode())

        msg = messages.crypto_pairing({
            tlv8.TLV_SEQ_NO: b'\x06',
            tlv8.TLV_ENCRYPTED_DATA: encrypted,
        })
        self.has_paired = True

        self._send(msg)
コード例 #13
0
def get_context(prime=None, generator=None, hash_func=None):
    return SRPContext(username,
                      password,
                      prime=prime,
                      generator=generator,
                      hash_func=hash_func)
コード例 #14
0
ファイル: test_context.py プロジェクト: xolian/srptools
def test_byte_hashes():
    static_salt = int_from_hex('99e50c9ad1bd2856')
    static_client_private = int_from_hex('2b557313c052bb0e24a3c7462e8f436769a54e8d325da794004cefab83ac8b71')
    static_server_private = int_from_hex(
        '57e997761d2aeb4c8dbfed9fde120c0ec730af1237e296f58649a6b3193ff21b36f5cfaed3049ee0051e5378f666f13d'
        '0c7c91040940a77a3ff1a461666c41e9aca3bd4747d74036e34941578553eb56d369638f796707425d0294809e81363f'
        'ac90af29c7fde1ae142f8c280e3c2e17f9c4d68f644de5406aac7d378b812a34')

    context = SRPContext('bouke', 'test')

    password_hash = context.get_common_password_hash(static_salt)
    password_verifier = context.get_common_password_verifier(password_hash)
    assert hex_from(password_verifier) == (
        '52e3ee0cde007d2e7cee87acca1c041999b528e56dec925112d30a63d8e814231c2cd3bac9ae40220c44d63029912f1f'
        '7dda878e938ab5bfe7b87b854bb8385020d765054d07424eb5749fcd90344dbc0372432f6db25ae12cca4584ea72270c'
        'a61d831540b10919a31fde1b7b9e1cc7110429d8bbde1a6fe005896697b91436')

    client_public = context.get_client_public(static_client_private)
    assert hex_from(client_public) == (
        'e18b11cddbfa709020fa2c67344a20e6704dba3e5ca6c4ca864b94ff5442965c80dfa751a9404feb2234fcd02d7f179d'
        'ca4e308d76af173ec4eacc13a8daf0237bf19d4ac0ae9a4db885fdb46d5107caea8f71a8db39eda96d594e216c632a0d'
        '9720d84e8abb82b3dfa67fad099e1c67b13081bb564b2369c6db5f10358680b2')

    server_public = context.get_server_public(password_verifier, static_server_private)
    assert hex_from(server_public) == (
        '0b3cc73f40a5fbdee992995dc26bfc43558803689798731fd303cdf18fdecbb5544f5caf960910f1b9449c772032be38'
        '2b22d8763104781793553977bfdbd7cd3b05af0bf00deee22d76b477275e3294713711e3fe97f34724f9580bf2c055e7'
        '8ae138664dfecaa2fe353768e30c3cc395541a929dc2af6a66e118ca937cffe8')

    common_secret = context.get_common_secret(server_public, client_public)
    assert hex_from(common_secret) == 'cb709a3c8a6767fda651ad6543436e4da2c85268'

    expected_premaster_secret = (
        '8c0ade0a5cc22507230bf092348a518fe9c29f1cbeb7a1a089ac070da5f5f7d540377fa30703164823017f421cc71237'
        '2cc2093228fc6b05a4c77f05216c7c911fbdc2ed63f48a1ecec9da8a1edda3c810c724d8c45f83acd48a6c05f33d36b4'
        '0ebca6db6f34a3f8e69289f7e49ef3492265d18488d447fb232b56306cb39a3a')

    server_premaster_secret = context.get_server_premaster_secret(
        password_verifier, static_server_private, client_public, common_secret)
    assert hex_from(server_premaster_secret) == expected_premaster_secret

    client_premaster_secret = context.get_client_premaster_secret(
        password_hash, server_public, static_client_private, common_secret)
    assert hex_from(client_premaster_secret) == expected_premaster_secret

    expected_session_key = b'86a5aff58ae7eca772b05bbb629f5b1c51677b14'

    server_session_key = context.get_common_session_key(server_premaster_secret)
    assert hex_from(server_session_key) == expected_session_key

    client_session_key = context.get_common_session_key(client_premaster_secret)
    assert hex_from(client_session_key) == expected_session_key

    client_session_key_prove = context.get_common_session_key_proof(
        client_session_key, static_salt, server_public, client_public)
    assert hex_from(client_session_key_prove) == b'001961fb3aa5c24c437df55a18a41cabce3d57b4'

    server_session_key_prove = context.get_common_session_key_proof_hash(
        server_session_key, client_session_key_prove, client_public)
    assert hex_from(server_session_key_prove) == b'f0a6d49e5037f34b770a8e2de9ec5e3c0880953b'
コード例 #15
0
from mysecrets import HOST,PORT, cbc_oracle_iv as iv
from mysecrets import cbc_oracle_ciphertext as ciphertext

DATA_SIZE = 65535

USERNAME = '******'
PASSWORD = '******'


if __name__ == '__main__':


    # the user should receive the salt from the server, before generating the context

    context = SRPContext(USERNAME, PASSWORD)
    username, password_verifier, client_salt = context.get_user_data_triplet()
    print(username)
    print(password_verifier)
    print(client_salt)
    prime = context.prime
    gen = context.generator

    print(prime)
    print(gen)


    server = remote(HOST, PORT)

    auth_data = json.dumps({'username': username, 'prime': prime, 'generator': gen, 'password_verifier': password_verifier, 'salt': client_salt})
    print(auth_data)
コード例 #16
0
ファイル: pairing.py プロジェクト: egreenie/trakt-for-appletv
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"))
コード例 #17
0
    # print(prime)
    # print(gen)

    # receive user data
    user_data = conn.recv(DATA_SIZE).decode()
    auth_data = json.loads(user_data)
    # print(auth_data)
    print("username = "******"prime    = " + str(auth_data['prime']))
    print("generator= " + str(auth_data['generator']))
    print("verifier = " + str(auth_data['password_verifier']))

    # generate user-based server parameters
    server_session = SRPServerSession(
        SRPContext(auth_data['username'],
                   prime=auth_data['prime'],
                   generator=auth_data['generator']),
        auth_data['password_verifier'])

    server_public = server_session.public
    print("server public= " + str(server_public))

    server_data = json.dumps({'server_verifier':
                              server_public})  # 'server_salt' : server_salt})
    # print(server_data)
    conn.send(server_data.encode())

    # receive client parameters
    user_data = conn.recv(DATA_SIZE).decode()
    client_parameters = json.loads(user_data)
    # print(client_parameters)
コード例 #18
0
ファイル: remote.py プロジェクト: tgu/SRP
subparsers.is_required = True
subparsers.add_parser("server")
subparsers.add_parser("client")

parser.add_argument("username", type=hex_encoded_utf8)
parser.add_argument("password", type=hex_encoded_utf8)

args = parser.parse_args()

prime = groups[args.group][0]
generator = groups[args.group][1]
hash_func = algorithms[args.algorithm]
ensure_hash_size = ensure_hash_sizes[args.algorithm]
context = SRPContext(args.username,
                     args.password,
                     prime=prime,
                     generator=generator,
                     hash_func=hash_func)

if args.command == "server":
    if args.salt:
        salt = args.salt
        password_verifier = value_encode(
            context.get_common_password_verifier(
                context.get_common_password_hash(unhexlify(salt))))
    else:
        _, password_verifier, salt = context.get_user_data_triplet()

    print("v:", password_verifier)

    # Client => Server: username, A
コード例 #19
0
PASSWORD = '******'

if __name__ == '__main__':


    server = remote(HOST, PORT)

    received_data = server.recv(DATA_SIZE).decode()
    server_data = json.loads(received_data)
    print(server_data['prime'])
    print(server_data['generator'])
    print(server_data['B'])
    print(server_data['server_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_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})
    print(client_parameters)

    server.send(client_parameters.encode())

    print("KEY = " + str(client_session.key))

    # receive the server key proof
コード例 #20
0
from srptools import SRPContext, SRPServerSession, SRPClientSession

username = '******'
password = '******'

### at the client, where the password is known

srp_context = SRPContext(username, password)  # gen, prime
user, password_verifier, salt = srp_context.get_user_data_triplet()
gen = srp_context.generator
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
コード例 #21
0
ファイル: test_context.py プロジェクト: xolian/srptools
def test_context():

    def to_hex_u(val):
        return hex_from(val).upper()

    static_salt = int_from_hex('BEB25379D1A8581EB5A727673A2441EE')
    static_client_private = int_from_hex('60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393')
    static_server_private = int_from_hex('E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20')

    context = SRPContext(
        'alice',
        'password123',
        multiplier='7556AA045AEF2CDD07ABAF0F665C3E818913186F',
    )

    assert context.prime_b64
    assert context.generator_b64

    password_hash = context.get_common_password_hash(static_salt)
    assert to_hex_u(password_hash) == '94B7555AABE9127CC58CCF4993DB6CF84D16C124'

    password_verifier = context.get_common_password_verifier(password_hash)
    assert to_hex_u(password_verifier) == (
        '7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D8129BADA1F1822223CA1A605B530E379BA4729FDC59'
        'F105B4787E5186F5C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5EA53D15C1AFF87B2B9DA6E04'
        'E058AD51CC72BFC9033B564E26480D78E955A5E29E7AB245DB2BE315E2099AFB')

    client_public = context.get_client_public(static_client_private)
    assert to_hex_u(client_public) == (
        '61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC44352E8903211C04692272D8B2D1A5358A2CF1B6E'
        '0BFCF99F921530EC8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44BE087EF06530E69F66615261'
        'EEF54073CA11CF5858F0EDFDFE15EFEAB349EF5D76988A3672FAC47B0769447B')

    server_public = context.get_server_public(password_verifier, static_server_private)
    assert to_hex_u(server_public) == (
        'BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9'
        'B681CBF87837EC996C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A'
        '00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58')

    common_secret = context.get_common_secret(server_public, client_public)
    assert to_hex_u(common_secret) == 'CE38B9593487DA98554ED47D70A7AE5F462EF019'

    expected_premaster_secret = (
        'B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D233861E359B48220F7C4693C9AE12B0A6F67809F'
        '0876E2D013800D6C41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F3499B200210DCC1F10EB3394'
        '3CD67FC88A2F39A4BE5BEC4EC0A3212DC346D7E474B29EDE8A469FFECA686E5A')

    expected_session_key = b'017EEFA1CEFC5C2E626E21598987F31E0F1B11BB'

    server_premaster_secret = context.get_server_premaster_secret(
        password_verifier, static_server_private, client_public, common_secret)
    assert to_hex_u(server_premaster_secret) == expected_premaster_secret

    client_premaster_secret = context.get_client_premaster_secret(
        password_hash, server_public, static_client_private, common_secret)
    assert to_hex_u(client_premaster_secret) == expected_premaster_secret

    server_session_key = context.get_common_session_key(server_premaster_secret)
    assert to_hex_u(server_session_key) == expected_session_key

    client_session_key = context.get_common_session_key(client_premaster_secret)
    assert to_hex_u(client_session_key) == expected_session_key

    client_session_key_prove = context.get_common_session_key_proof(
        client_session_key, static_salt, server_public, client_public)
    assert to_hex_u(client_session_key_prove) == b'3F3BC67169EA71302599CF1B0F5D408B7B65D347'

    server_session_key_prove = context.get_common_session_key_proof_hash(
        server_session_key, client_session_key_prove, client_public)
    assert to_hex_u(server_session_key_prove) == b'9CAB3C575A11DE37D3AC1421A9F009236A48EB55'