Encrypting Text (Part 1)

by Oct 15, 2019

Let’s take a look at a safe way of encrypting text on a computer. The below Protect-Text function takes any text and encrypts it automatically, no password needed. Instead of a password, it uses either your user account and machine, or just your machine as a secret.

If you use -Scope LocalMachine, any user on that machine can decrypt the text, but if the text is leaked to someone else, it cannot be decrypted on another machine. If you use -Scope CurrentUser, only the person that encrypted the text can decrypt it, and only on the machine where it was encrypted. This encryption method is ideal for saving your own private passwords.

In addition, and to increase security, an (optional) password can be added on top. When specified, the same restrictions apply, but in addition the password needs to be known to decrypt the text.

Note that you can also control the text encoding. Make sure to use the same encoding for both encryption and decryption.

Here is the encryption function:

function Protect-Text
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [String]
        $SecretText,
        
        [string]
        $Password='',
        
        [string]
        [ValidateSet('CurrentUser','LocalMachine')]
        $scope = 'CurrentUser',

        [string]
        [ValidateSet('UTF7','UTF8','UTF32','Unicode','ASCII','Default')]
        $Encoding = 'Default',

        [Switch]
        $ReturnByteArray
        
    )
    begin
    {
        Add-Type -AssemblyName System.Security
        if ([string]::IsNullOrEmpty($Password))
        {
            $optionalEntropy = $null
        }
        else
        {
            $optionalEntropy = [System.Text.Encoding]::$Encoding.GetBytes($Password)
        }
    }
    process
    {
        try
        {
            $userData = [System.Text.Encoding]::$Encoding.GetBytes($SecretText)
            $bytes = [System.Security.Cryptography.ProtectedData]::Protect($userData, $optionalEntropy, $scope)
            if ($ReturnByteArray)
            {
                $bytes
            }
            else
            {
                [Convert]::ToBase64String($bytes)
            }
        }
        catch
        {
            throw "Protect-Text: Unable to protect text. $_"
        }
    }

And this would be a result:

 
PS> Protect-Text -SecretText 'I am encrypted' -scope LocalMachine 
AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAF8Hpm9A5A0upZysoxLlvgwQAAAACAAAAAAAQZgAAAAEAACAAAACbOsUoDuZJXNkWIzfAABxktVg+Txn7A8Rz
SCvFP7I9YQAAAAAOgAAAAAIAACAAAABz7G7Tpuoje9meLOuugzx1WSoOUfaBtGPM/XZHytjC8hAAAAApt/TDhJ9EqeWEPLIDkd4bQAAAAAN0Q503Pa7X
MxIMOnaO7qd3LKXJa4qhht+jc+Z0HaaV5/md83ipP1vefYAAUXdj8qv4eREeCBSGMqvKjbaOsOg=  
 

If you’re wondering how to turn this Base64-encoded text back to the original text, check our next tip!


Twitter This Tip! ReTweet this Tip!