PEMEncrypt.psm1

# Base module contents

function Import-Assemblies {
    Param()
    Begin {
        $dllPath = if ($PSVersionTable.PSVersion.Major -ge 6) {
            [System.IO.Path]::Combine($PSScriptRoot,'bin','netstandard')
        }
        else {
            [System.IO.Path]::Combine($PSScriptRoot,'bin','netfx')
        }
    }
    Process {
        try {
            $bouncyCastleDll = Join-Path $dllPath 'BouncyCastle.Crypto.dll'
            Add-Type -Path $bouncyCastleDll -ErrorAction SilentlyContinue | Out-Null
        }
        catch {
            $Global:Error.Remove($Global:Error[0])
        }
        try {
            $PEMEncrypt = Join-Path $dllPath 'SCRTHQ.PEMEncrypt.dll'
            Add-Type -Path $PEMEncrypt -ReferencedAssemblies $bouncyCastleDll -ErrorAction SilentlyContinue | Out-Null
        }
        catch {
            $Global:Error.Remove($Global:Error[0])
        }
    }
}


function Protect-PEMString {
    <#
    .SYNOPSIS
    Encrypts a string by using a public RSA key.
 
    .DESCRIPTION
    Encrypts a string by using a public RSA key.
 
    .PARAMETER StringToEncrypt
    The plain-text string that you would like to encrypt with the public key.
 
    .PARAMETER PublicKey
    The full or relative path to the public key OR the key itself in string format.
 
    .EXAMPLE
    # Using a password-less private key
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public.pem
    $encrypted | Unprotect-PEMString -PrivateKey .\private.pem
 
    .EXAMPLE
    # Use Get-Credential to prompt for credentials so it's not in plain text
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public_des3.pem
    $keyCreds = Get-Credential -UserName key -Message 'Please enter the password for the private key'
    $encrypted | Unprotect-PEMString -PrivateKey .\private_des3.pem -Password $keyCreds.Password
 
    .EXAMPLE
    # Build a SecureString using a plain-text password
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public_des3.pem
    $password = ConvertTo-SecureString 'P@$$w0rd' -AsPlainText -Force
    $encrypted | Unprotect-PEMString -PrivateKey .\private_des3.pem -Password $password
    #>

    [OutputType('System.String')]
    [CmdletBinding()]
    Param (
        [parameter(Mandatory,Position = 0,ValueFromPipeline)]
        [Alias('String')]
        [String[]]
        $StringToEncrypt,
        [parameter(Mandatory,Position = 1)]
        [Alias('PublicKeyPath','Key')]
        [String]
        $PublicKey
    )
    Begin {
        Import-Assemblies
        if ([System.IO.File]::Exists($PublicKey)) {
            $PublicKey = ([System.IO.File]::ReadAllText((Resolve-Path $PublicKey).Path))
        }
    }
    Process {
        foreach ($string in $StringToEncrypt) {
            try {
                [SCRTHQ.PEMEncrypt.Crypto]::Encrypt(
                    $string,
                    $PublicKey
                )
            }
            catch {
                $PSCmdlet.ThrowTerminatingError($_)
            }
        }
    }
}

Export-ModuleMember -Function 'Protect-PEMString'

function Unprotect-PEMString {
    <#
    .SYNOPSIS
    Decrypts an encrypted string by using the private RSA key corresponding to the public key the string was encrypted with.
 
    .DESCRIPTION
    Decrypts an encrypted string by using the private RSA key corresponding to the public key the string was encrypted with.
 
    .PARAMETER StringToDecrypt
    The Base64 string that you would like to decrypt with the private key.
 
    .PARAMETER PrivateKey
    The full or relative path to the private key OR the key itself in string format.
 
    .PARAMETER Password
    A SecureString containing the password for the private key, if applicable.
 
    Exclude if the private key does not have a password.
 
    .EXAMPLE
    # Using a password-less private key
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public.pem
    $encrypted | Unprotect-PEMString -PrivateKey .\private.pem
 
    .EXAMPLE
    # Use Get-Credential to prompt for credentials so it's not in plain text
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public_des3.pem
    $keyCreds = Get-Credential -UserName key -Message 'Please enter the password for the private key'
    $encrypted | Unprotect-PEMString -PrivateKey .\private_des3.pem -Password $keyCreds.Password
 
    .EXAMPLE
    # Build a SecureString using a plain-text password
    $encrypted = 'Hello','How are you today?' | Protect-PEMString -PublicKey .\public_des3.pem
    $password = ConvertTo-SecureString 'P@$$w0rd' -AsPlainText -Force
    $encrypted | Unprotect-PEMString -PrivateKey .\private_des3.pem -Password $password
    #>

    [OutputType('System.String')]
    [CmdletBinding()]
    Param (
        [parameter(Mandatory,Position = 0,ValueFromPipeline)]
        [Alias('String')]
        [String[]]
        $StringToDecrypt,
        [parameter(Mandatory,Position = 1)]
        [Alias('PrivateKeyPath','Key')]
        [String]
        $PrivateKey,
        [parameter(Position = 2)]
        [AllowNull()]
        [SecureString]
        $Password
    )
    Begin {
        Import-Assemblies
        if ([System.IO.File]::Exists($PrivateKey)) {
            $PrivateKey = ([System.IO.File]::ReadAllText((Resolve-Path $PrivateKey).Path))
        }
    }
    Process {
        foreach ($string in $StringToDecrypt) {
            try {
                if ($PSBoundParameters.ContainsKey('Password')) {
                    [SCRTHQ.PEMEncrypt.Crypto]::Decrypt(
                        $string,
                        $PrivateKey,
                        (New-Object PSCredential 'user',$Password).GetNetworkCredential().Password
                    )
                }
                else {
                    [SCRTHQ.PEMEncrypt.Crypto]::Decrypt(
                        $string,
                        $PrivateKey
                    )
                }
            }
            catch {
                $PSCmdlet.ThrowTerminatingError($_)
            }
        }
    }
}

Export-ModuleMember -Function 'Unprotect-PEMString'