Source code for config_yourself.provider.datakey

# Copyright 2018 Blink Health LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     https://www.apache.org/licenses/LICENSE-2.0

from .base import CryptoService
from builtins import bytes
from config_yourself.exceptions import ConfigException
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt

NONCE_BYTE_SIZE = 32
SALT_SIZE = 12


[docs]class DataKeyService(CryptoService): """The DataKeyService implements a CryptoService that uses an in-file data key to decrypt secrets :param bytes key: this file's datakey """ def __init__(self, key): self._cipher = AESGCM(key)
[docs] def decrypt(self, ciphertext): nonce, data = ciphertext[0:NONCE_BYTE_SIZE], ciphertext[NONCE_BYTE_SIZE:] try: return self._cipher.decrypt(nonce, data, b"") except InvalidTag: raise DataKeyDecryptError("Could not decrypt")
[docs]def decrypt_key_with_password(key, password): """Turns a key and password into a scrypt key :param bytes key: The key bytes, containing the salt and encrypted key :param str password: The password in plaintext to derive the key from :returns: The decrypted key contained in ``key`` :rtype: bytes """ # get the salt and encrypted key salt, encryptedKey = key[0:SALT_SIZE], key[SALT_SIZE:] # re-create the file's key with the provided password and salt derivedKey = Scrypt( salt, backend=default_backend(), # key length for AES length=32, # The cost parameter n=32 * 1024, # same values as go-config-yourself r=8, p=1, ).derive(bytes(password, "utf-8")) # Return the decrypted key using the derived key return DataKeyService(derivedKey).decrypt(encryptedKey)
[docs]class DataKeyDecryptError(ConfigException): pass