Exemplo n.º 1
0
class VirgilKeyGenerator(KeyGeneratorInterface):
    """
    Represents key pair entity for virgil_crypto lib usage only
    """
    def __init__(self,
                 key_type: str,
                 private_key=None,
                 public_key=None,
                 ec_type=VirgilKeyPair.Type_EC_SECP256R1,
                 hash_type=HashAlgorithm.SHA256):
        self._crypto = VirgilCrypto()
        self._crypto.signature_hash_algorithm = hash_type
        self.__hash_type = hash_type
        self.__key_type = key_type
        self.__ec_type = ec_type
        self.__public_key = None if not public_key else b64_to_bytes(
            public_key)
        self.__private_key = None if not private_key else b64_to_bytes(
            private_key)
        self.__key_id = None
        self.__signature = None
        self.device_serial = None

    def generate(self,
                 *,
                 signature_limit=None,
                 rec_pub_keys=None,
                 signer_key: Optional[KeyGeneratorInterface] = None,
                 private_key_base64: Optional[str] = None,
                 start_date: Optional[int] = 0,
                 expire_date: Optional[int] = 0,
                 meta_data: Optional[bytes] = bytes()):
        def make_signature():
            byte_buffer = io.BytesIO()

            # vs_pubkey_dated_t
            byte_buffer.write(
                start_date.to_bytes(4, byteorder='big', signed=False))
            byte_buffer.write(
                expire_date.to_bytes(4, byteorder='big', signed=False))
            byte_buffer.write(
                self.key_type_secmodule.to_bytes(1,
                                                 byteorder='big',
                                                 signed=False))
            byte_buffer.write(
                self.ec_type_secmodule.to_bytes(1,
                                                byteorder='big',
                                                signed=False))
            byte_buffer.write(
                len(meta_data).to_bytes(2, byteorder='big', signed=False))
            byte_buffer.write(meta_data)
            byte_buffer.write(b64_to_bytes(self.public_key))

            bytes_to_sign = byte_buffer.getvalue()
            return signer_key.sign(to_b64(bytes_to_sign), long_sign=False)

        if private_key_base64:
            self.__private_key = b64_to_bytes(private_key_base64)
            virgil_priv_key = self._crypto.import_private_key(
                self.__private_key)
            virgil_pubkey = self._crypto.extract_public_key(virgil_priv_key)
            self.__public_key = VirgilKeyPair.publicKeyToDER(
                virgil_pubkey.raw_key)[-65:]

        if self.__private_key is None:
            virgil_key_pair = VirgilKeyPair.generate(self.ec_type)
            self.__private_key = VirgilKeyPair.privateKeyToDER(
                virgil_key_pair.privateKey())
            self.__public_key = VirgilKeyPair.publicKeyToDER(
                virgil_key_pair.publicKey())[-65:]

        if signer_key:
            self.__signature = make_signature()

        return self

    @property
    def ec_type(self):
        return self.__ec_type

    @property
    def hash_type(self):
        return self.__hash_type

    @property
    def private_key(self):
        return to_b64(self.__private_key)

    @property
    def public_key(self):
        return to_b64(self.__public_key)

    @property
    def public_key_full(self):
        virgil_private_key = self._crypto.import_private_key(
            b64_to_bytes(self.private_key))
        return to_b64(self._crypto.extract_public_key(virgil_private_key))

    @property
    def signature(self):
        return self.__signature

    @property
    def key_id(self):
        return CRCCCITT().calculate(b64_to_bytes(self.public_key))

    @property
    def key_type(self):
        return self.__key_type

    def sign(self, data, long_sign=False):
        data = b64_to_bytes(data)
        private_key = b64_to_bytes(self.private_key)
        signature = self._crypto.sign(
            data, self._crypto.import_private_key(private_key))
        if not long_sign:
            signature = VirgilSignExtractor.extract_sign(signature)
        return to_b64(signature)

    def verify(self, data, signature, long_sign=False):
        data = b64_to_bytes(data)
        public_key = b64_to_bytes(
            self.public_key_full)  # verify  signature with full public key
        return self._crypto.verify(data, signature,
                                   self._crypto.import_public_key(public_key))

    def encrypt(self, data):
        data = b64_to_bytes(data)
        public_key = b64_to_bytes(
            self.public_key_full)  # encrypt with full public key
        encrypted = self._crypto.encrypt(
            data, self._crypto.import_public_key(public_key))
        return to_b64(encrypted)

    def decrypt(self, data):
        data = b64_to_bytes(data)
        private_key = b64_to_bytes(self.private_key)
        decrypted = self._crypto.decrypt(
            data, self._crypto.import_private_key(private_key))
        return to_b64(decrypted)
Exemplo n.º 2
0
# Generate keys for the receiving end of the location.
receiver_keys = crypto.generate_key_pair()
receiver_public_key = receiver_keys.public_key
receiver_private_key = receiver_keys.private_key

# Generate keys for the middle man!
middleman_keys = crypto.generate_key_pair()
middleman_public_key = middleman_keys.public_key
middleman_private_key = middleman_keys.private_key

# Create location to send to receiver. This will be intercepted by the middleman.
location = "lat=42.361145,long=-71.057083"
location_data = location.encode()

# Ok encrypt a message for the receiver. It requires the receivers public key and the message being sent.
receiver_list = [receiver_public_key]
encrypted_data = crypto.encrypt(location_data, *receiver_list)

# Time for the middleman to decrypt data. He is not on the receiver list, so it shouldn't work!
middleman_decrypted_data = crypto.decrypt(encrypted_data, middleman_private_key)

# Decrypt the message from the host. This is the receivers part now. This is why the private key is here
decrypted_data = crypto.decrypt(encrypted_data, receiver_private_key)
decrypted_message = bytes(decrypted_data).decode()

# Print decrypted message for the intended receiver.
print(decrypted_message)

# Print the decrypted data for the middleman.
print(middleman_decrypted_data)
Exemplo n.º 3
0
# First, create Virgil Crypto object
crypto = VirgilCrypto()

# Create public/private keys for the sender. Default algorithm is EC_X25519
sender_keys = crypto.generate_key_pair()
sender_public_key = sender_keys.public_key
sender_private_key = sender_keys.private_key

# Create public/private keys for the receiver.
receiver_keys = crypto.generate_key_pair()
receiver_public_key = receiver_keys.public_key
receiver_private_key = receiver_keys.private_key

# Create data that we want to verify between the two clients. This data won't be sent yet, just for signature validation purposes.
location = "lat=42.361145,long=-71.057083"
location_data = location.encode()

# List of public keys that will receive the location data
receiver_list = [receiver_public_key]

# Encrypt the data using AES-256
encrypted_data = crypto.encrypt(location_data, *receiver_list)

# Now, this is the receivers side (The person receiving the location from the sender). This would be a separate individual client.
# If we were to use sockets, this would be another file for a different host interacting with the server. The receivers private
# key is available because they are receiving the encrypted message on their device.
decrypted_data = crypto.decrypt(encrypted_data, receiver_private_key)
decrypted_message = bytes(decrypted_data).decode()

print(decrypted_message)