BattleFaction2019.psm1

function Get-CaesarCipher {
    [CmdletBinding()]
    param (
        [parameter(Mandatory = $true)]
        [string]$Text,
        [parameter(Mandatory = $true)]
        [int]$SecretNumber,
        [string]$RootString =  $([char[]]$(32..126) -join ''),
        [switch]$Encode,
        [switch]$Decode
    )
    
    begin {
        # If you are decoding, you need to reverse the lookup
        if ($Decode) { $SecretNumber = -$SecretNumber }
        # Modulus is used to keep the values inside array of possible positions
        $Modulus = $RootString.length
        Write-Verbose "Modulus: $Modulus"
        If ($SecretNumber -lt 0) {
            $SecretNumber = $Modulus + ($SecretNumber % $Modulus)
        }
        Write-Verbose $SecretNumber
    }
    
    process {
        # Build 2 hashtables. One for looking a letter based on poition in the string and one for looking up the position in the string based on the letter
        $Counter = @{ }
        $Letter = @{ }
        $i = 0
        [int[]][char[]]$RootString | ForEach-Object { $Counter.add($i, $_); $Letter.Add($_, $i); $i++ }

        # Convert original chars to the char ints matching the secret number
        $Converted = [int[]][char[]]$Text | ForEach-Object {
            try {
                if ($_ -eq 10 -or $_ -eq 13) { $_ } else {
                    $no = $letter[$_]
                    $Counter[$($($no + $SecretNumber) % $Modulus)]
                }
            }
            catch {
                Write-Warning "Error on $_"
            }
        }
    }
    
    end {
        # Just joining the string would remove new line carriage return, formatting a string allows them to expand correctly
        $str = ""
        for ($j = 0; $j -le $Converted.count - 1; $j++) { $str += "{$j}" }
        $str -f $($Converted.foreach{ [char]$_ })
    }
}
function Protect-Message {
    [CmdletBinding()]
    param (
        $Message,
        [securestring]$Password,
        [System.IO.FileInfo]$File
    )
    
    begin {
        $certPath = "$env:Temp\BattleCert.pfx"
        $UserInfo = @{
            User     = $env:USERNAME
            Computer = $env:COMPUTERNAME
            Date     = (Get-Date).ToString()
        } | ConvertTo-Json
    }
    
    process {
        $certName = 'BattleFaction' + ((Get-Random -InputObject (0..9) -count 4) -join '')
        $battleCert = New-SelfSignedCertificate -DnsName $certName -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsage KeyEncipherment, DataEncipherment, KeyAgreement -Type DocumentEncryptionCert
        $Message | Protect-CmsMessage -To $battleCert.Subject -OutFile $File.FullName
        $Exported = $battleCert | Export-PfxCertificate -FilePath $certPath -Password $Password
        $fileContentBytes = get-content $certPath -Encoding Byte
        $certString = [System.Convert]::ToBase64String($fileContentBytes)
        Add-Content -value $certString -Path $File.FullName -Stream Cert
        Add-Content -value $UserInfo -Path $File.FullName -Stream UserInfo


    }
    
    end {
        Get-Childitem -Path Cert:\CurrentUser\My -DocumentEncryptionCert | where { $_.Subject -eq $battleCert.subject } | Remove-Item
        Remove-item $certPath
    }
}
function Unprotect-Message {
    [CmdletBinding()]
    param (
        [System.IO.FileInfo]$MessageFile,
        [SecureString]$Password,
        [switch]$ThisMessageWillSelfDestruct
    )
    
    begin {
        $cert = Get-Content $MessageFile.FullName -Stream Cert
        $userInfo = Get-Content $MessageFile.FullName -Stream UserInfo | convertfrom-json
        $certPath = "$env:Temp\BattleCert.pfx"
    }
    
    process {
        [IO.File]::WriteAllBytes($certPath, [Convert]::FromBase64String($cert))
        $battleCert = Import-PfxCertificate -CertStoreLocation "Cert:\CurrentUser\My" -FilePath $certPath -Password $Password
        $Message = Unprotect-CmsMessage -Path $MessageFile.FullName
        $userMessageString = "Message was generated on {0} by {1} at {2}" -f $userInfo.Computer, $userInfo.User, $userInfo.Date
        Write-Verbose $userMessageString
        $Message
    }
    
    end {
        Get-Childitem -Path Cert:\CurrentUser\My -DocumentEncryptionCert | where { $_.Subject -eq $battleCert.subject } | Remove-Item
        Remove-item $certPath
        if ($ThisMessageWillSelfDestruct){Remove-Item $MessageFile}
    }
}