Example #1
0
    def test_pyuecc(self):
        (pub1, pri1) = pyuecc.make_key()
        logging.debug('pub key %s' % pub1)
        logging.debug('pri key %s' % pri1)
        assert len(pub1) == 64
        assert len(pri1) == 64

        (pub2, pri2) = pyuecc.make_key()
        spri1 = pyuecc.shared_secret(pub1, pri2)
        spri2 = pyuecc.shared_secret(pub2, pri1)
        logging.debug('shared key %s' % spri1)
        assert spri1 == spri2

        cpub1 = pyuecc.compress(pub1)
        logging.debug('compressed key %s' % cpub1)
        assert len(cpub1) == 33

        _pub1 = pyuecc.decompress(cpub1)
        logging.debug('decompressed key %s' % _pub1)
        assert _pub1 == pub1

        msg = b'test'
        sig1 = pyuecc.sign(pri1, msg)
        ok = pyuecc.verify(pub1, msg, sig1)
        logging.debug('signature %s' % sig1)
        assert ok

        ok = pyuecc.verify(pub2, msg, sig1)
        assert not ok
Example #2
0
    def encrypt_handshake(self, msg, remote_permanent_public_b64):
        """
        encrypt handshake message structured:

        KEY - 33 bytes, the sender's ephemeral exchange public key in
              compressed format
        IV - 4 bytes, a random but unique value determined by the sender
        INNER - the AES-256-CTR encrypted inner packet ciphertext
        HMAC - 4 bytes, the calculated HMAC of all of the previous
               KEY+IV+INNER bytes

        :param bytes msg: handshake message
        :param bytes remote_permanent_public_b64: remote node pubkey
        :return: encrypted bytes data
        """

        remote_permanent_public = \
            base64.b64decode(remote_permanent_public_b64)
        compressed_pkey = pyuecc.compress(self.remote_ephemeral_public)
        shared_key = get_sha256(
            pyuecc.shared_secret(remote_permanent_public,
                                 self.remote_ephemeral_private)
        )
        iv = pack('I', self.seq)
        self.seq += 1
        aes = AES.new(shared_key, AES.MODE_CTR, counter=IVCounter(iv))
        enc_msg = aes.encrypt(msg.encode())
        hmac_key = pyuecc.shared_secret(remote_permanent_public,
                                        self.mynode.private) + iv
        sig = fold3(hmac.new(hmac_key, enc_msg, hashlib.sha256).digest())
        self.token = fold1(get_sha256(compressed_pkey[0:16]))
        return compressed_pkey + iv + enc_msg + sig
Example #3
0
    def decrypt_handshake(self, msg):
        """
        decrypt handshake message structured:
        decoded msg must be json str and key 'public_key' must be included.

        :param bytes msg: encrypted handshake message
        :return: decrypted message
        """
        received_public = pyuecc.decompress(msg[0:33])
        self.create_channel_keys(received_public)

        shared_key = get_sha256(
            pyuecc.shared_secret(received_public, self.mynode.private)
        )
        aes = AES.new(shared_key, AES.MODE_CTR, counter=IVCounter(msg[33:37]))
        dec_msg = aes.encrypt(msg[37:-4]).decode()

        try:
            jmsg = json.loads(dec_msg)
        except Exception:
            logging.error('msg is not json')
            return None

        if 'public_key' not in jmsg:
            logging.error('public_key not included')
            return None

        remote_permanent_public = base64.b64decode(jmsg['public_key'])
        hmac_key = pyuecc.shared_secret(remote_permanent_public,
                                        self.mynode.private) + msg[33:37]
        sig = fold3(hmac.new(hmac_key, msg[37:-4], hashlib.sha256).digest())
        if sig != msg[-4:]:
            logging.error('signature unmatched')
            return None

        return dec_msg
Example #4
0
    def create_channel_keys(self, received_key):
        """
        create channel key by
        encryption key: SHA256(secret, sent-KEY, received-KEY) / 2
        decryption key: SHA256(secret, received-KEY, sent-KEY) / 2
        where secret is derived from ECDH from ephemeral keys.

        :param bytes received_key: recived epheram key.
        """
        shared_key = pyuecc.shared_secret(received_key,
                                          self.remote_ephemeral_private)
        t = shared_key + self.remote_ephemeral_public + received_key
        self.channel_enckey = get_sha256(t)
        t = shared_key + received_key + self.remote_ephemeral_public
        self.channel_deckey = get_sha256(t)