Last active
July 12, 2024 21:27
-
-
Save mtahle/3548069e126e08567bb8f5c29fdb76a0 to your computer and use it in GitHub Desktop.
encrypt and decrypt a backup file using AWS Key Management Service (KMS) and AWS S3.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# This script provides functionality to encrypt and decrypt a backup file using AWS Key Management Service (KMS) and AWS S3. | |
# It takes two main commands: 'encrypt' and 'decrypt'. | |
# The 'encrypt' command encrypts the backup file using a data encryption key (DEK) generated by AWS KMS. | |
# The encrypted backup file and the encrypted DEK are then uploaded to an S3 bucket. | |
# The 'decrypt' command downloads the encrypted backup file and the encrypted DEK from the S3 bucket. | |
# It then decrypts the backup file using the DEK and saves it to a local directory. | |
#Author: | |
# Mujahed Al-Tahleh,DevOps Consultant, AWS Professional Services, GitHub: @mtahle | |
set -e | |
# Set locale to handle byte sequences correctly | |
export LC_ALL=C | |
# Function to encrypt the file | |
encrypt() { | |
# Check if required environment variables are set | |
: "${KMS_KEY_ID?Need to set KMS_KEY_ID}" | |
: "${S3_BUCKET_NAME?Need to set S3_BUCKET_NAME}" | |
# Generate a data encryption key (DEK) and capture both plaintext and ciphertext | |
DEK_OUTPUT=$(aws kms generate-data-key --key-id $KMS_KEY_ID --key-spec AES_256 --output json) | |
# Extract the plaintext DEK and the ciphertext blob from the output | |
DEK_PLAINTEXT=$(echo $DEK_OUTPUT | jq -r '.Plaintext' | base64 --decode | tr -d '\n\r ') | |
DEK_CIPHERTEXT=$(echo $DEK_OUTPUT | jq -r '.CiphertextBlob') | |
# Encrypt the file using the plaintext DEK | |
openssl enc -aes-256-cbc -salt -in /shared/file.txt -out /shared/file.txt.enc -pass pass:$DEK_PLAINTEXT | |
echo $DEK_CIPHERTEXT > /tmp/dek_ciphertext | |
# Organize S3 by date | |
DATE=$(date +%Y-%m-%d) | |
# Upload the encrypted file and encrypted DEK to S3 | |
aws s3 cp /shared/file.txt.enc s3://$S3_BUCKET_NAME/backups/$DATE/file.txt.enc | |
aws s3 cp /tmp/dek_ciphertext s3://$S3_BUCKET_NAME/backups/$DATE/dek_ciphertext | |
shred -u /shared/* | |
shred -u /tmp/dek_ciphertext | |
echo "File encryption and upload successful." | |
} | |
# Function to decrypt the file | |
decrypt() { | |
# Check if required environment variables are set | |
: "${KMS_KEY_ID?Need to set KMS_KEY_ID}" | |
: "${S3_BUCKET_NAME?Need to set S3_BUCKET_NAME}" | |
: "${DATE?Need to set DATE}" # The date folder where the file and DEK are stored | |
echo "Downloading encrypted DEK and file from S3..." | |
aws s3 cp s3://$S3_BUCKET_NAME/backups/$DATE/dek_ciphertext /tmp/dek_ciphertext | |
aws s3 cp s3://$S3_BUCKET_NAME/backups/$DATE/file.txt.enc /tmp/file.txt.enc | |
# Verify the files are downloaded successfully | |
if [ ! -f /tmp/dek_ciphertext ]; then | |
echo "Error: Failed to download /tmp/dek_ciphertext" | |
exit 1 | |
fi | |
if [ ! -f /tmp/file.txt.enc ]; then | |
echo "Error: Failed to download /tmp/file.txt.enc" | |
exit 1 | |
fi | |
cat /tmp/dek_ciphertext | base64 --decode > /tmp/decoded_dek_ciphertext | |
# Decrypt the DEK using AWS KMS | |
DEK_PLAINTEXT=$(aws kms decrypt --ciphertext-blob fileb:///tmp/decoded_dek_ciphertext --output text --query Plaintext | base64 --decode ) | |
if [ -z "$DEK_PLAINTEXT" ]; then | |
echo "Error: Failed to decrypt DEK" | |
exit 1 | |
fi | |
# Decrypt the file using the plaintext DEK | |
openssl enc -d -aes-256-cbc -in /tmp/file.txt.enc -out /tmp/file.txt -pass pass:$DEK_PLAINTEXT | |
# Verify the decryption was successful | |
if [ ! -f /tmp/file.txt ]; then | |
echo "Error: Decryption failed" | |
exit 1 | |
fi | |
# Clean up | |
unset DEK_PLAINTEXT | |
rm /tmp/dek_ciphertext | |
echo "Decryption successful. Decrypted file is at /tmp/file.txt" | |
} | |
# Main script logic | |
case "$1" in | |
encrypt|e) | |
encrypt | |
;; | |
decrypt|d) | |
decrypt | |
;; | |
*) | |
echo "Usage: $0 {encrypt|decrypt}" | |
echo " encrypt: Encrypt the file" | |
echo " decrypt: Decrypt the file" | |
echo " Note: When using 'decrypt', ensure to set the DATE environment variable in the format YYYY-MM-DD" | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment