Movatterモバイル変換


[0]ホーム

URL:


ContentsMenuExpandLight modeDark modeAuto light/dark, in light modeAuto light/dark, in dark modeClose MenuSkip to content
Boto3 1.39.9 documentation
Light LogoDark Logo
Boto3 1.39.9 documentation

Feedback

Do you have a suggestion to improve this website or boto3?Give us feedback.

Back to top

Encrypt and decrypt a file

The example program uses AWS KMS keys to encrypt and decrypt a file.

A master key, also called a Customer Master Key or CMK, is created and used to generate a data key.The data key is then used to encrypt a disk file. The encrypted data key is stored withinthe encrypted file. To decrypt the file, the data key is decrypted and then used to decryptthe rest of the file. This manner of using master and data keys is called envelope encryption.

To encrypt and decrypt data, the example uses the well-known Pythoncryptography package.This package is not part of the Python standard library and must be installed separately, forexample, with thepip command.

pipinstallcryptography

Retrieve an existing master key

Master keys are created, managed, and stored within AWS KMS. A KMS master key is also referred toas a customer master key or CMK. An AWS storage cost is incurred for each CMK, therefore, one CMK isoften used to manage multiple data keys.

The exampleretrieve_cmk function searches for an existing CMK. A key description is specifiedwhen a CMK is created, and this description is used to identify and retrieve the desired key. Ifmany CMKs exist, they are processed in batches until either the desired key is found or all keys areexamined.

If the example function finds the desired CMK, it returns both the CMK’s ID and its ARN (AmazonResource Name). Either of these identifiers can be used to reference the CMK in subsequent callsto AWS KMS methods.

defretrieve_cmk(desc):"""Retrieve an existing KMS CMK based on its description    :param desc: Description of CMK specified when the CMK was created    :return Tuple(KeyId, KeyArn) where:        KeyId: CMK ID        KeyArn: Amazon Resource Name of CMK    :return Tuple(None, None) if a CMK with the specified description was    not found    """# Retrieve a list of existing CMKs# If more than 100 keys exist, retrieve and process them in batcheskms_client=boto3.client('kms')try:response=kms_client.list_keys()exceptClientErrorase:logging.error(e)returnNone,Nonedone=Falsewhilenotdone:forcmkinresponse['Keys']:# Get info about the key, including its descriptiontry:key_info=kms_client.describe_key(KeyId=cmk['KeyArn'])exceptClientErrorase:logging.error(e)returnNone,None# Is this the key we're looking for?ifkey_info['KeyMetadata']['Description']==desc:returncmk['KeyId'],cmk['KeyArn']# Are there more keys to retrieve?ifnotresponse['Truncated']:# No, the CMK was not foundlogging.debug('A CMK with the specified description was not found')done=Trueelse:# Yes, retrieve another batchtry:response=kms_client.list_keys(Marker=response['NextMarker'])exceptClientErrorase:logging.error(e)returnNone,None# All existing CMKs were checked and the desired key was not foundreturnNone,None

Create a customer master key

If the example does not find an existing CMK, it creates a new one and returns its ID and ARN.

defcreate_cmk(desc='Customer Master Key'):"""Create a KMS Customer Master Key    The created CMK is a Customer-managed key stored in AWS KMS.    :param desc: key description    :return Tuple(KeyId, KeyArn) where:        KeyId: AWS globally-unique string ID        KeyArn: Amazon Resource Name of the CMK    :return Tuple(None, None) if error    """# Create CMKkms_client=boto3.client('kms')try:response=kms_client.create_key(Description=desc)exceptClientErrorase:logging.error(e)returnNone,None# Return the key ID and ARNreturnresponse['KeyMetadata']['KeyId'],response['KeyMetadata']['Arn']

Create a data key

To encrypt a file, the examplecreate_data_key function creates a data key. The data key iscustomer managed and does not incur an AWS storage cost. The example creates a data key foreach file it encrypts, but it’s possible to use a single data key to encrypt multiple files.

The example function returns the data key in both its plaintext and encrypted forms. Theplaintext form is used to encrypt the data. The encrypted form will be stored with the encryptedfile. The data key is associated with a CMK which is capable of decrypting the encrypted data keywhen necessary.

defcreate_data_key(cmk_id,key_spec='AES_256'):"""Generate a data key to use when encrypting and decrypting data    :param cmk_id: KMS CMK ID or ARN under which to generate and encrypt the    data key.    :param key_spec: Length of the data encryption key. Supported values:        'AES_128': Generate a 128-bit symmetric key        'AES_256': Generate a 256-bit symmetric key    :return Tuple(EncryptedDataKey, PlaintextDataKey) where:        EncryptedDataKey: Encrypted CiphertextBlob data key as binary string        PlaintextDataKey: Plaintext base64-encoded data key as binary string    :return Tuple(None, None) if error    """# Create data keykms_client=boto3.client('kms')try:response=kms_client.generate_data_key(KeyId=cmk_id,KeySpec=key_spec)exceptClientErrorase:logging.error(e)returnNone,None# Return the encrypted and plaintext data keyreturnresponse['CiphertextBlob'],base64.b64encode(response['Plaintext'])

Encrypt a file

Theencrypt_file function creates a data key and uses it to encrypt the contents of a disk file.

The encryption operation is performed by aFernet object created by the Pythoncryptographypackage.

The encrypted form of the data key is saved within the encrypted file and will be used in the futureto decrypt the file. The encrypted file can be decrypted by any program with the credentials todecrypt the encrypted data key.

defencrypt_file(filename,cmk_id):"""Encrypt a file using an AWS KMS CMK    A data key is generated and associated with the CMK.    The encrypted data key is saved with the encrypted file. This enables the    file to be decrypted at any time in the future and by any program that    has the credentials to decrypt the data key.    The encrypted file is saved to <filename>.encrypted    Limitation: The contents of filename must fit in memory.    :param filename: File to encrypt    :param cmk_id: AWS KMS CMK ID or ARN    :return: True if file was encrypted. Otherwise, False.    """# Read the entire file into memorytry:withopen(filename,'rb')asfile:file_contents=file.read()exceptIOErrorase:logging.error(e)returnFalse# Generate a data key associated with the CMK# The data key is used to encrypt the file. Each file can use its own# data key or data keys can be shared among files.# Specify either the CMK ID or ARNdata_key_encrypted,data_key_plaintext=create_data_key(cmk_id)ifdata_key_encryptedisNone:returnFalselogging.info('Created new AWS KMS data key')# Encrypt the filef=Fernet(data_key_plaintext)file_contents_encrypted=f.encrypt(file_contents)# Write the encrypted data key and encrypted file contents togethertry:withopen(filename+'.encrypted','wb')asfile_encrypted:file_encrypted.write(len(data_key_encrypted).to_bytes(NUM_BYTES_FOR_LEN,byteorder='big'))file_encrypted.write(data_key_encrypted)file_encrypted.write(file_contents_encrypted)exceptIOErrorase:logging.error(e)returnFalse# For the highest security, the data_key_plaintext value should be wiped# from memory. Unfortunately, this is not possible in Python. However,# storing the value in a local variable makes it available for garbage# collection.returnTrue

Decrypt a data key

To decrypt an encrypted file, the encrypted data key used to perform the encryption must firstbe decrypted. This operation is performed by the exampledecrypt_data_key function which returnsthe plaintext form of the key.

defdecrypt_data_key(data_key_encrypted):"""Decrypt an encrypted data key    :param data_key_encrypted: Encrypted ciphertext data key.    :return Plaintext base64-encoded binary data key as binary string    :return None if error    """# Decrypt the data keykms_client=boto3.client('kms')try:response=kms_client.decrypt(CiphertextBlob=data_key_encrypted)exceptClientErrorase:logging.error(e)returnNone# Return plaintext base64-encoded binary data keyreturnbase64.b64encode((response['Plaintext']))

Decrypt a file

The exampledecrypt_file function first extracts the encrypted data key from the encrypted file. Itthen decrypts the key to get its plaintext form and uses that to decrypt the file contents.

The decryption operation is performed by aFernet object created by the Pythoncryptographypackage.

defdecrypt_file(filename):"""Decrypt a file encrypted by encrypt_file()    The encrypted file is read from <filename>.encrypted    The decrypted file is written to <filename>.decrypted    :param filename: File to decrypt    :return: True if file was decrypted. Otherwise, False.    """# Read the encrypted file into memorytry:withopen(filename+'.encrypted','rb')asfile:file_contents=file.read()exceptIOErrorase:logging.error(e)returnFalse# The first NUM_BYTES_FOR_LEN bytes contain the integer length of the# encrypted data key.# Add NUM_BYTES_FOR_LEN to get index of end of encrypted data key/start# of encrypted data.data_key_encrypted_len=int.from_bytes(file_contents[:NUM_BYTES_FOR_LEN],byteorder='big') \+NUM_BYTES_FOR_LENdata_key_encrypted=file_contents[NUM_BYTES_FOR_LEN:data_key_encrypted_len]# Decrypt the data key before using itdata_key_plaintext=decrypt_data_key(data_key_encrypted)ifdata_key_plaintextisNone:returnFalse# Decrypt the rest of the filef=Fernet(data_key_plaintext)file_contents_decrypted=f.decrypt(file_contents[data_key_encrypted_len:])# Write the decrypted file contentstry:withopen(filename+'.decrypted','wb')asfile_decrypted:file_decrypted.write(file_contents_decrypted)exceptIOErrorase:logging.error(e)returnFalse# The same security issue described at the end of encrypt_file() exists# here, too, i.e., the wish to wipe the data_key_plaintext value from# memory.returnTrue
On this page

[8]ページ先頭

©2009-2025 Movatter.jp