Beispiel #1
0
 def test_open_with_wrong_associated_data(self):
     """Ensure 'open' raises IntegrityError if wrong associated data is given"""
     bad_ad = [b"INVALID"]
     for ex in SIVExample.load():
         siv = SIV(ex.key)
         with self.assertRaises(IntegrityError):
             siv.open(ex.ciphertext, bad_ad)
Beispiel #2
0
def wrap_key_owner(passphrase, data_key):
    """
    data_key must be encoded

    Using argon2.low_level function, which is technically a hazmat
    function, but it doesn't appear to have any dangerous problems. We
    can't use the argon2.PasswordHasher() functions because they compress
    the hash and metadata using Blake2b and you can't extract the raw
    bytes of the hash or salt, which we need for the SIV.
    """

    #derive key using passphrase and salt
    salt = os.urandom(16)
    derived_key = argon2.low_level.hash_secret_raw(
        passphrase.encode(),
        salt,
        time_cost=1,
        memory_cost=8,
        parallelism=1,
        hash_len=32,
        type=argon2.low_level.Type.I)

    # wrap the data key using the derived key
    siv = SIV(derived_key)
    ciphertext = siv.seal(data_key)

    # add salt to the start of ciphertext
    ciphertext = salt + ciphertext
    return ciphertext
Beispiel #3
0
 def decrypt(self: object, passphrase: bytes) -> None:
     with open(self.in_path, 'rb') as in_file:
         salt = in_file.read(self.SALT_SIZE)
         key = self._derive_key(passphrase, salt)
         siv = SIV(key)
         nonce = in_file.read(self.NONCE_SIZE)
         plaintext = siv.open(in_file.read(), [nonce])
     self._extract(plaintext)
Beispiel #4
0
    def test_open_with_wrong_key(self):
        """Ensure 'open' raises IntegrityError if wrong key is given"""
        bad_key = b"\x01" * 32
        siv = SIV(bad_key)

        for ex in SIVExample.load():
            with self.assertRaises(IntegrityError):
                siv.open(ex.ciphertext, ex.ad)
Beispiel #5
0
 def encrypt(self: object) -> [bytes, str]:
     passphrase = self._gen_xkcd_phrase()
     salt = os.urandom(self.SALT_SIZE)
     key = self._derive_key(passphrase.encode('utf-8'), salt)
     siv = SIV(key)
     nonce = os.urandom(self.NONCE_SIZE)
     ciphertext = salt + nonce + siv.seal(self._archive(), [nonce])
     return ciphertext, passphrase
Beispiel #6
0
def dec_file(filepath, data_key):
    siv = SIV(data_key)
    with open(filepath, 'rb') as myfile:
        ciphertext = myfile.read()
        # first 16 bytes are the nonce
        nonce = ciphertext[:16]
        plaintext = siv.open(ciphertext[16:], [nonce])
        return plaintext.decode()
    return None
Beispiel #7
0
def enc_file(filepath):
    key = SIV.generate_key()
    siv = SIV(key)
    nonce = os.urandom(16)

    with open(filepath, 'r') as myfile:
        data = myfile.read().encode()
        ciphertext = siv.seal(data, [nonce])
        return (key, nonce, nonce + ciphertext)
        #returning ciphertext with the nonce (first 16 bytes)
    return None
Beispiel #8
0
    def setup(self):

        password = self.ask_password()

        # Generate Salt
        if not self.config["salt"]:
            salt = urandom(SALT_SIZE)
            self.config["salt"] = binascii.hexlify(salt)

        # Derive key from password and initialize SIV
        key = self.derive_key(password)
        self.engine = SIV(key)
Beispiel #9
0
    def dec_file(self):
        """
        Decrypt file and return plaintext
        """

        with open(self.input_file, 'rb') as f:
            data = f.read()
            siv = SIV(self.k)
            nonce = data[:16]
            pt = siv.open(data[16:], [nonce])

            return pt.decode()
Beispiel #10
0
def encryption_machine(msg):
    encrypt = []

    key = SIV.generate_key()
    siv = SIV(key)
    nonce = os.urandom(16)  # create a random nonce
    ciphertext = siv.seal(msg, [nonce])  # msg is in byte

    encrypt.append(ciphertext)
    encrypt.append(nonce)
    encrypt.append(key)
    return encrypt  # we create a list with the nonce, the key and the ciphertext to be able to decrypt it later
Beispiel #11
0
class AES(Encryption):

    default_options = {"salt": None}

    pubkey = None

    def setup(self):

        password = self.ask_password()

        # Generate Salt
        if not self.config["salt"]:
            salt = urandom(SALT_SIZE)
            self.config["salt"] = binascii.hexlify(salt)

        # Derive key from password and initialize SIV
        key = self.derive_key(password)
        self.engine = SIV(key)

    def derive_key(self, password):

        salt = binascii.unhexlify(self.config["salt"])
        pw_bytes = bytes(password, "utf-8")

        dk = hash_secret_raw(
            pw_bytes,
            salt,
            time_cost=ARGON2_TIME_COST,
            memory_cost=ARGON2_MEMORY_COST,
            parallelism=ARGON2_PARALLELISM,
            hash_len=ARGON2_HASH_LEN,
            type=ARGON2_TYPE,
        )

        return dk

    def encrypt(self, data):

        nonce = urandom(NONCE_SIZE)

        if not isinstance(data, bytes):
            data = bytes(data, "utf-8")

        sealed_data = self.engine.seal(data, [nonce])

        return (sealed_data, nonce)

    def decrypt(self, payload):

        data = self.engine.open(payload[0], [payload[1]])

        return data
Beispiel #12
0
    def _gen_key():
        """
        Generate key, initialize SIV object, and return relevant data
        """

        k = SIV.generate_key()
        siv = SIV(k)

        ret = {
            "k": k,
            "siv": siv,
            "nonce": os.urandom(16)
        }

        return ret
Beispiel #13
0
def unwrap_key_owner(passphrase, wrapped_key_ciphertext):
    #derive key using passphrase and salt
    salt = wrapped_key_ciphertext[:16]
    derived_key = argon2.low_level.hash_secret_raw(
        passphrase.encode(),
        salt,
        time_cost=1,
        memory_cost=8,
        parallelism=1,
        hash_len=32,
        type=argon2.low_level.Type.I)

    # unwrap the data key using the derived key
    siv = SIV(derived_key)
    data_key = siv.open(wrapped_key_ciphertext[16:])
    return data_key
def main():
    allocate_kms_key()
    allocate_ddb_table()
    #Allocate encryption keys, store encrypted rows
    plaintext_dek = allocate_dek()
    siv = SIV(plaintext_dek)

    for item_key in valid_partition_keys:
        p_key =  encrypt_pk(siv, item_key)
        response = dynamodb.put_item(
            TableName=ddb_table_name,
            Item={
                'PK': {
                    'B': p_key,
                },
                'PK_plain': {
                    "S": str(item_key)
                }
            }
        )
        if response:
            print("Wrote item with encrypted PK '{}', with plaintext {}".format(p_key, str(item_key)))
    #Re-build the SIV module from a fresk DEK to prove the key is deterministic.
    plaintext_dek = allocate_dek()
    siv = SIV(plaintext_dek)
    for item_key in valid_partition_keys:
        p_key =  encrypt_pk(siv, item_key)
        response = dynamodb.get_item(
            TableName=ddb_table_name,
            Key={
                'PK': {
                    'B': p_key,
                }
            }
        )
        if response:
            print("Read item with plaintext PK {}, with decrypted plaintext PK {}. Both should match.".format(response['Item']['PK_plain']['S'], decrypt_pk(siv, response['Item']['PK']['B'])))
Beispiel #15
0
 def test_open(self):
     """Ensure the 'open' passes all AES-SIV test vectors"""
     for ex in PMACSIVExample.load():
         siv = SIV(ex.key, PMAC)
         plaintext = siv.open(ex.ciphertext, ex.ad)
         self.assertEqual(plaintext, ex.plaintext)
Beispiel #16
0
 def test_seal(self):
     """Ensure the 'seal' method passes all AES-SIV test vectors"""
     for ex in PMACSIVExample.load():
         siv = SIV(ex.key, PMAC)
         ciphertext = siv.seal(ex.plaintext, ex.ad)
         self.assertEqual(ciphertext, ex.ciphertext)
Beispiel #17
0
 def test_generate_key(self):
     """Ensure we can generate random keys with the right default size"""
     key = SIV.generate_key()
     self.assertEqual(len(key), 32)
Beispiel #18
0
def dec_str(ciphertext, data_key):
    siv = SIV(data_key)
    nonce = ciphertext[:16]
    plaintext = siv.open(ciphertext[16:], [nonce])
    return plaintext.decode()
Beispiel #19
0
def decryption_machine(encrypt):
    siv = SIV(encrypt[2])
    plaintext = siv.open(encrypt[0], [encrypt[1]])
    return plaintext