Ejemplo n.º 1
0
class BLECDH:
    def __init__(self, curve=NIST256p):
        self.ecdh = ECDH(curve)
        self.local_public_key = None
        self.sharedsecret = ''

    def create_public_key(self):
        self.ecdh.generate_private_key()
        self.local_public_key = self.ecdh.get_public_key()
        ret = binascii.hexlify(
            self.local_public_key.to_string()).decode('utf-8')
        bflb_utils.printf('local public key:')
        bflb_utils.printf(ret)
        return ret

    def create_shared_key(self, peer_pk):
        self.ecdh.load_received_public_key_bytes(binascii.unhexlify(peer_pk))
        self.sharedsecret = self.ecdh.generate_sharedsecret_bytes()
        ret = binascii.hexlify(self.sharedsecret).decode('utf-8')
        bflb_utils.printf('secret key:')
        bflb_utils.printf(ret)
        return ret
Ejemplo n.º 2
0
def EncryptMessage(publicKey_hex, plainText_string):
    if publicKey_hex[:2] == '0x':
        publicKey_hex = publicKey_hex[2:]
    publicKey_bin = bytearray.fromhex(publicKey_hex)

    # Generate the temporary key
    ecdh = ECDH(curve=SECP256k1)
    ecdh.generate_private_key()

    ephemPubKeyEncoded = bytearray.fromhex(
        ecdh.get_public_key().to_string().hex())

    # Load the public key
    publicKey = VerifyingKey.from_string(publicKey_bin, curve=SECP256k1)

    # ECDH => get the shared secret
    ecdh.load_received_public_key(publicKey)

    px = ecdh.generate_sharedsecret_bytes()

    # compute the encription and MAC keys
    hash_px = SHA512.new(data=px).digest()
    encryptionKey = hash_px[:32]
    macKey = hash_px[32:]

    # cipher the plain text
    iv = Random.get_random_bytes(16)
    plaintext = plainText_string.encode(encoding='utf_8')
    ciphertext = AES256CbcEncrypt(plaintext, encryptionKey, iv)

    # compute the MAC
    dataToMac = iv + bytearray([4]) + ephemPubKeyEncoded + ciphertext
    mac = hmac.new(macKey, dataToMac, 'sha256').digest()

    #build the output
    serializedCiphertext = iv + bytearray(
        [4]) + ephemPubKeyEncoded + mac + ciphertext
    return serializedCiphertext.hex()
Ejemplo n.º 3
0
from ecdsa import ECDH, NIST256p

ecdh = ECDH(curve=NIST256p)
ecdh.generate_private_key()
local_public_key = ecdh.get_public_key()
#send `local_public_key` to remote party and receive `remote_public_key` from remote party
with open("remote_public_key.pem") as e:
    remote_public_key = e.read()
ecdh.load_received_public_key_pem(remote_public_key)
secret = ecdh.generate_sharedsecret_bytes()
Ejemplo n.º 4
0
class SecureChannel:
    def __init__(self, loglevel=logging.WARNING):
        logger.setLevel(loglevel)
        logger.debug("In __init__")
        self.initialized_secure_channel = False
        self.sc_privkey = None
        self.sc_pubkey = None
        self.sc_peer_pubkey = None
        self.sc_IV = None
        self.sc_IVcounter = None
        self.shared_key = None
        self.derived_key = None
        self.mac_key = None

        self.ecdh = ECDH(curve=SECP256k1)
        self.ecdh.generate_private_key()
        self.sc_pubkey = self.ecdh.get_public_key()
        self.sc_pubkey_serialized = self.sc_pubkey.to_string(
            encoding='uncompressed')

    def initiate_secure_channel(self, peer_pubkey_bytes):
        logger.debug("In initiate_secure_channel()")

        self.sc_IVcounter = 1

        #using ecdsa
        self.sc_peer_pubkey = VerifyingKey.from_string(peer_pubkey_bytes,
                                                       curve=SECP256k1)
        self.ecdh.load_received_public_key(self.sc_peer_pubkey)
        self.shared_key = self.ecdh.generate_sharedsecret_bytes()

        #logger.debug("Shared key:"+ self.shared_key.hex()) #debug

        mac = hmac.new(self.shared_key, "sc_key".encode('utf-8'), sha1)
        self.derived_key = mac.digest()[:16]
        mac = hmac.new(self.shared_key, "sc_mac".encode('utf-8'), sha1)
        self.mac_key = mac.digest()

        # alternative derivation
        # tmp_key= sha256(self.shared_key).digest()
        # self.derived_key = tmp_key[:16]
        # tmp_key= sha256(tmp_key).digest()
        # self.mac_key= tmp_key[:20]

        # logger.debug("Derived_key key:"+ self.derived_key.hex()) #debug
        # logger.debug("Mac_key key:"+ self.mac_key.hex()) #debug

        self.initialized_secure_channel = True

    def encrypt_secure_channel(self, data_bytes):
        logger.debug("In encrypt_secure_channel()")
        if not self.initialized_secure_channel:
            raise UninitializedSecureChannelError(
                'Secure channel is not initialized')

        ## for encryption, the data is padded with PKCS#7 (done by PADDING_DEFAULT)
        # blocksize= 16
        # size=len(apdu)
        # padsize= blocksize - (size%blocksize)
        # apdu= apdu+ [padsize]*padsize

        key = self.derived_key
        iv = urandom(12) + (self.sc_IVcounter).to_bytes(4, byteorder='big')

        aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv)
        aes = pyaes.Encrypter(aes_cbc, padding=pyaes.PADDING_DEFAULT)
        ciphertext = aes.feed(data_bytes) + aes.feed()

        self.sc_IVcounter += 2

        data_to_mac = iv + len(ciphertext).to_bytes(
            2, byteorder='big') + ciphertext
        mac = hmac.new(self.mac_key, data_to_mac, sha1).digest()

        return (iv, ciphertext, mac)

    def decrypt_secure_channel(self, iv, ciphertext):
        logger.debug("In decrypt_secure_channel()")
        if not self.initialized_secure_channel:
            raise UninitializedSecureChannelError(
                'Secure channel is not initialized')

        key = self.derived_key

        aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv)
        aes = pyaes.Decrypter(aes_cbc, padding=pyaes.PADDING_DEFAULT)
        decrypted = aes.feed(ciphertext) + aes.feed()

        # #remove padding (already done with PADDING_DEFAULT)
        # #logger.debug(f'Plaintext with padding: {toHexString(plaintext)}')
        # plaintext= list(plaintext)
        # pad= plaintext[-1]
        # plaintext=plaintext[0:-pad]
        # #logger.debug(f'Plaintext without padding: {toHexString(plaintext)}')

        return list(decrypted)