DMapper24.psm1

#===============================================================================
# DMapper24 - Version 1.0.0
#===============================================================================
#
# Copyright (c) 2021 - Jean-Paul CORVO
# Licence CeCILL-B-v1
# + http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
# + http://www.cecill.info/licences/Licence_CeCILL_V1-fr.txt
#
#===============================================================================
#
# +----------------------------------------------------------------------------
# | BouncyCastle.Crypto.dll
# +----------------------------------------------------------------------------
# | https://www.bouncycastle.org/csharp/download/bccrypto-csharp-1.8.10-bin.zip
# +----------------------------------------------------------------------------
# | Copyright (c) 2000 - 2021 The Legion of the Bouncy Castle Inc.
# | (https://www.bouncycastle.org)
# |
# | Permission is hereby granted, free of charge, to any person obtaining a copy
# | of this software and associated documentation files (the "Software"), to deal
# | in the Software without restriction, including without limitation the rights
# | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# | copies of the Software, and to permit persons to whom the Software is
# | furnished to do so, subject to the following conditions:
# |
# | The above copyright notice and this permission notice shall be included in
# | all copies or substantial portions of the Software.
# |
# | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# | SOFTWARE.
# +----------------------------------------------------------------------------
#
#===============================================================================

<#
 .SYNOPSIS
  Initialize (or load) .Net Bouncy Castle dll

 .DESCRIPTION
  To acces encryptions functions, we need to load .Net Bouncy Castle dll.
  The Dll is found in https://www.bouncycastle.org/csharp/download/bccrypto-csharp-1.8.10-bin.zip

 .PARAMETER DllUri
  Values are:
  + "C:\Path\To\BouncyCastle.Crypto.dll
  + ".\BouncyCastle.Crypto.dll

 .EXAMPLE
   Initialize-DMapper24BouncyCastle
   Initialize-DMapper24BouncyCastle ".\BouncyCastle.Crypto.dll
   Initialize-DMapper24BouncyCastle "C:\Path\To\BouncyCastle.Crypto.dll
   Initialize-DMapper24BouncyCastle -DllUri "C:\Path\To\BouncyCastle.Crypto.dll
 .NOTES
  -
#>

function Initialize-DMapper24BouncyCastle
{
    #-----------------------------------
    [CmdletBinding()]
    param
    (
        [Parameter(Position=0,Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [String]
        $DllUri = (Join-Path $PSScriptRoot 'BouncyCastle.Crypto.dll')
    )
    #-----------------------------------
    if((Test-Path $DLLUri) -eq $false)
    {
        throw 'BouncyCastle.Crypto.dll not found'
    }
    if("Org.BouncyCastle.Crypto.Engines.RijndaelEngine" -as [type])
    {}
    else
    {
        Add-Type -Path $DllUri -PassThru | Out-Null
    }
    #-----------------------------------
}

<#
 .SYNOPSIS
  Create a new cipher for encryption or decryption

 .DESCRIPTION
  Create a new cipher for encryption or decryption with caracteristics:
  + Rijndael
  + CBC
  + BlockSize = 256
  + KeySize = 256
  + IVSize = 256 (Identical to BlockSize)
  + Pkcs7Padding

 .PARAMETER Mode
  Values are:
  + "Encrypt" for encryption
  + "Decrypt" for decryption

 .EXAMPLE
   # New cipher
   Get-DMapper24Cipher -Mode "Encrypt"
   Get-DMapper24Cipher -Mode "Decrypt"
 .NOTES
  -
#>

function Get-DMapper24Cipher
{
    #-----------------------------------
    [CmdletBinding()]
    [OutputType([Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher])]
    param
    (
        [Parameter(Position=0,Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Encrypt', 'Decrypt')]
        [String]
        $Mode
    )
    [bool] $IsEncryptMode = $Mode -match 'Encrypt'
    #-----------------------------------
    Initialize-DMapper24BouncyCastle
    #-----------------------------------
    $Engine      = [Org.BouncyCastle.Crypto.Engines.RijndaelEngine]::new(256)
    $BlockCipher = [Org.BouncyCastle.Crypto.Modes.CbcBlockCipher]::new($Engine)
    $Padding     = [Org.BouncyCastle.Crypto.Paddings.Pkcs7Padding]::new()
    $Cipher      = [Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher]::new($BlockCipher,$Padding)

    $Key = '2a5Tr35zHFr4453g51'
    $KeyBytes = [Text.Encoding]::ASCII.GetBytes($Key)
    $Hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
    $KeyHashedBytes = $Hasher.ComputeHash($KeyBytes)
    $KeyParam = [Org.BouncyCastle.Crypto.Parameters.KeyParameter]::new($KeyHashedBytes)

    $Iv = '968285a5770ac921fc2256e57d821bde4d16b78872d2b1d02eda356164fc51c4'
    $IvBytes = [byte[]] -split ($Iv -replace '..', '0x$& ')
    $KeyParamWithIV = [Org.BouncyCastle.Crypto.Parameters.ParametersWithIV]::new($KeyParam,$IvBytes,0,32)

    $Cipher.Init($IsEncryptMode,$KeyParamWithIV)
    return $Cipher
    #-----------------------------------
}

<#
 .SYNOPSIS
  Encrypt a text

 .DESCRIPTION
  Encrypt a text with Mapper24 encryption scheme

 .PARAMETER Text
  Values are "Hello World" or whatever you want

 .EXAMPLE
   ConvertTo-DMapper24EncryptedText "Hello Gwada"
   uuN3ZzVC9eCSpUSnY2M/jKUJHKqHq2JYwX3Hu2hu9hI=

 .EXAMPLE
   "Hello Gwada" | ConvertTo-DMapper24EncryptedText
    uuN3ZzVC9eCSpUSnY2M/jKUJHKqHq2JYwX3Hu2hu9hI=

 .NOTES
  -
#>

function ConvertTo-DMapper24EncryptedText
{
    #-----------------------------------
    [CmdletBinding()]
    [OutputType([string])]
    param
    (
        [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [ValidateNotNullOrEmpty()]
        [String]
        $PlainText
    )
    #-----------------------------------
    Begin
    {
        Initialize-DMapper24BouncyCastle
        $Cipher = Get-DMapper24Cipher -Mode 'Encrypt'
    }
    Process
    {
        $PlainTextBytes = [Text.Encoding]::ASCII.GetBytes($PlainText)
        $CipherTextBytes = [byte[]]::new($Cipher.GetOutputSize($PlainTextBytes.Length))

        $Length = $Cipher.ProcessBytes($PlainTextBytes,0,$PlainTextBytes.Length,$CipherTextBytes,0)
        $Cipher.DoFinal($CipherTextBytes,$Length) | Out-Null

        $CipherText = [System.Convert]::ToBase64String($CipherTextBytes)
        $CipherText
    }
    End
    {
    }
    #-----------------------------------
}

<#
 .SYNOPSIS
  Decrypt a text

 .DESCRIPTION
  Decrypt a text with Mapper24 encryption scheme

 .PARAMETER Text
  CipherText

 .EXAMPLE
  ConvertFrom-DMapper24EncryptedText "uuN3ZzVC9eCSpUSnY2M/jKUJHKqHq2JYwX3Hu2hu9hI="

 .EXAMPLE
  ConvertFrom-DMapper24EncryptedText -CipherText "uuN3ZzVC9eCSpUSnY2M/jKUJHKqHq2JYwX3Hu2hu9hI="

 .EXAMPLE
  "uuN3ZzVC9eCSpUSnY2M/jKUJHKqHq2JYwX3Hu2hu9hI=" | ConvertFrom-DMapper24EncryptedText

 .NOTES
  -
#>

function ConvertFrom-DMapper24EncryptedText
{
    #-----------------------------------
    [CmdletBinding()]
    [OutputType([string])]
    param
    (
        [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [ValidateNotNullOrEmpty()]
        [String]
        $CipherText
    )
    #-----------------------------------
    Begin
    {
        Initialize-DMapper24BouncyCastle
        $Cipher = Get-DMapper24Cipher -Mode 'Decrypt'
    }
    Process
    {
        $CipherTextBytes = [System.Convert]::FromBase64String($CipherText)
        $PlainTextBytes = [byte[]]::new($Cipher.GetOutputSize($CipherTextBytes.Length))

        $Length = $Cipher.ProcessBytes($CipherTextBytes,0,$CipherTextBytes.Length,$PlainTextBytes,0)
        $Cipher.DoFinal($PlainTextBytes,$Length) | Out-Null

        $PlainText = [Text.Encoding]::UTF8.GetString($PlainTextBytes)
        $PlainText
    }
    End
    {
    }
    #-----------------------------------
}

<#
 .SYNOPSIS
  Test encryption and decryption functions

 .DESCRIPTION
  Test simple encryption and decryption of text

 .EXAMPLE
  Test-DMapper24EncryptDecrypt

 .NOTES
  -
#>

function Test-DMapper24EncryptDecrypt
{
    #-----------------------------------
    [CmdletBinding()]
    #-----------------------------------
    $i = "azerty"
    $o = "ov7Fmu9GHkOT+nn48AC/l5g1KXyhGnj0wy6olV5cw+E="
    $ResultTest1 = ($i | ConvertTo-DMapper24EncryptedText) -eq $o
    Write-Output "Test #1"
    Write-Output "+ Encrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest1)"
    #-----------------------------------
    $i = "totoblo"
    $o = "4WYFxVmOJ7ySMCGgor5psO73T2tyEgNXBf+PKplqQUo="
    $ResultTest2 = ($i | ConvertTo-DMapper24EncryptedText) -eq $o
    Write-Output "Test #2"
    Write-Output "+ Encrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest2)"
    #-----------------------------------
    $i = "aze123RTY456UIO7890p"
    $o = "wD9sxFV+UWaeBYE+DTw6otQDnnzTZVphDf73C1Amvds="
    $ResultTest3 = ($i | ConvertTo-DMapper24EncryptedText) -eq $o
    Write-Output "Test #3"
    Write-Output "+ Encrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest3)"
    #-----------------------------------
    #-----------------------------------
    $i = "ov7Fmu9GHkOT+nn48AC/l5g1KXyhGnj0wy6olV5cw+E="
    $o = "azerty"
    $ResultTest4 = ($i | ConvertFrom-DMapper24EncryptedText) -eq $o
    Write-Output "Test #4"
    Write-Output "+ Decrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest4)"
    #-----------------------------------
    $i = "4WYFxVmOJ7ySMCGgor5psO73T2tyEgNXBf+PKplqQUo="
    $o = "totoblo"
    $ResultTest5 = ($i | ConvertFrom-DMapper24EncryptedText) -eq $o
    Write-Output "Test #5"
    Write-Output "+ Decrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest5)"
    #-----------------------------------
    $i = "wD9sxFV+UWaeBYE+DTw6otQDnnzTZVphDf73C1Amvds="
    $o = "aze123RTY456UIO7890p"
    $ResultTest6 = ($i | ConvertFrom-DMapper24EncryptedText) -eq $o
    Write-Output "Test #6"
    Write-Output "+ Decrypt( $($i) ) -eq $($o)"
    Write-Output "+ Result: $($ResultTest6)"
    #-----------------------------------
}