Search code examples
amazon-s3powershell-2.0amazon-kms

encrypt/decrypt contents of whole folder in powershell using AWS KMS


Can anyone please help me in encrypting/decrypting the contents of files in folder using AWS KMS? I want powershell script to do the same. I would like to encrypt the folder before uploading to an amazon s3 bucket and want to decrypt it after downloading from the s3 bucket.

P.S : I am new to powershell scripting.

Thanks in advance!


Solution

  • You can find a good tutorial here from steven.

    I just copy paste his code that worked perfectly for me.

    To encrypt:

    function Invoke-KMSEncryptText
    (
        [Parameter(Mandatory=$true,Position=1,HelpMessage='PlainText to Encrypt')]
        [string]$plainText,
        [Parameter(Mandatory=$true,Position=2,HelpMessage='GUID of Encryption Key in KMS')]
        [string]$keyID,
        [Parameter(Mandatory=$true,Position=3)]
        [string]$region,
        [Parameter(Position=4)]
        [string]$AccessKey,
        [Parameter(Position=5)]
        [string]$SecretKey
    )
    {
        # memory stream
        [byte[]]$byteArray = [System.Text.Encoding]::UTF8.GetBytes($plainText)
        $memoryStream = New-Object System.IO.MemoryStream($byteArray,0,$byteArray.Length)
        # splat
        $splat = @{Plaintext=$memoryStream; KeyId=$keyID; Region=$Region;}
        if(![string]::IsNullOrEmpty($AccessKey)){$splat += @{AccessKey=$AccessKey;}}
        if(![string]::IsNullOrEmpty($SecretKey)){$splat += @{SecretKey=$SecretKey;}}
        # encrypt
        $encryptedMemoryStream = Invoke-KMSEncrypt @splat
        $base64encrypted = [System.Convert]::ToBase64String($encryptedMemoryStream.CiphertextBlob.ToArray())
        return $base64encrypted
    }
    

    To decrypt:

    function Invoke-KMSDecryptText
    (
        [Parameter(Mandatory=$true,Position=1,HelpMessage='CipherText base64 string to decrypt')]
        [string]$cipherText,
        [Parameter(Mandatory=$true,Position=2)]
        [string]$region,
        [Parameter(Position=3)]
        [string]$AccessKey,
        [Parameter(Position=4)]
        [string]$SecretKey
    )
    {
        # memory stream
        $encryptedBytes = [System.Convert]::FromBase64String($cipherText)
        $encryptedMemoryStreamToDecrypt = New-Object System.IO.MemoryStream($encryptedBytes,0,$encryptedBytes.Length)
        # splat
        $splat = @{CiphertextBlob=$encryptedMemoryStreamToDecrypt; Region=$Region;}
        if(![string]::IsNullOrEmpty($AccessKey)){$splat += @{AccessKey=$AccessKey;}}
        if(![string]::IsNullOrEmpty($SecretKey)){$splat += @{SecretKey=$SecretKey;}}
        # decrypt
        $decryptedMemoryStream = Invoke-KMSDecrypt @splat
        $plainText = [System.Text.Encoding]::UTF8.GetString($decryptedMemoryStream.Plaintext.ToArray())
        return $plainText
    }
    

    And he provides an example:

    Import-Module awspowershell
    # set your credentials to access AWS, key you want to encrypt with, and the region the key is stored
    $AccessKey = ''
    $SecretKey = ''
    $Region = 'eu-west-1'
    $keyID = ''
    $plainText = 'Secret'
    
    # Encrypt some plain text and write to host
    $cipherText = Invoke-KMSEncryptText -plainText $plainText -keyID $keyID -Region $Region -AccessKey $AccessKey -SecretKey $SecretKey
    Write-host $cipherText
    
    # Decrypt the cipher text and write to host
    $plainText = Invoke-KMSDecryptText -cipherText $cipherText -Region $Region -AccessKey $AccessKey -SecretKey $SecretKey
    Write-host $plainText