EncryptPaschwordsModule.ps1
param ($sourcefile) function derivekeyfrompassword ([object]$Password, [byte[]]$Salt) {# Returns the derived key for HMAC. if ($Password -is [string]) {$secure = ConvertTo-SecureString $Password -AsPlainText -Force} elseif ($Password -is [SecureString]) {$secure = $Password} else {throw "The Password must be a string or SecureString."} $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure) try {$plain = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)} finally {[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)} $pbkdf2 = [Security.Cryptography.Rfc2898DeriveBytes]::new($plain, $Salt, 100000, [Security.Cryptography.HashAlgorithmName]::SHA256) try {return $pbkdf2.GetBytes(64)} finally {$pbkdf2.Dispose()}} function protectbytesaeshmac ([byte[]]$Data, [byte[]]$Key) {# Derived from password, split into encryption & HMAC keys. $aesKey = $Key[0..31]; $hmacKey = $Key[32..63]; $iv = New-Object byte[] 16; [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($iv); $aes = [System.Security.Cryptography.Aes]::Create(); $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC; $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7; $aes.Key = $aesKey; $aes.IV = $iv; $encryptor = $aes.CreateEncryptor(); $cipherText = $encryptor.TransformFinalBlock($Data, 0, $Data.Length); $hmac = [System.Security.Cryptography.HMACSHA256]::new($hmacKey); $hmacData = $iv + $cipherText; $hmacBytes = $hmac.ComputeHash($hmacData); $encryptor.Dispose(); $aes.Dispose(); $hmac.Dispose(); return $hmacBytes + $hmacData} function encryptmodulefile ([string]$sourcepath, [SecureString]$Password) {# Encrypt file # Error-checking. Write-Host "Encrypting from $sourcepath"; $sourcepath = Resolve-Path $sourcepath; $script:outputpath = $sourcepath -replace "\.\w+$", ".enc" if (-not (Test-Path $sourcepath)) {Write-Host -ForegroundColor Red "Source file not found!"; return} # Generate salt and key. $Salt = [byte[]]::new(16); [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($Salt); $Key = derivekeyfrompassword $Password $Salt # Compress. $content = [System.IO.File]::ReadAllText($sourcepath); [byte[]]$raw = [System.Text.Encoding]::UTF8.GetBytes($content); $ms = [System.IO.MemoryStream]::new(); $gzip = [System.IO.Compression.GzipStream]::new($ms, [System.IO.Compression.CompressionMode]::Compress); $gzip.Write($raw, 0, $raw.Length); $gzip.Close(); [byte[]]$compressed = $ms.ToArray() # Add HMAC. $protected = protectbytesaeshmac -Data $compressed -Key $Key try {[IO.File]::WriteAllBytes($script:outputpath, $Salt + $protected); Write-Host -ForegroundColor Green "Write operation succeeded"; $powershell = Split-Path $profile; Add-Content -Path "$powershell\Modules\Paschwords\.privilege\validhashes.sha256" -Value "# Paschwords.enc ($(Get-Date))`n$((Get-FileHash -Algorithm SHA256 $powershell\Modules\Paschwords\Paschwords.enc).Hash)"} catch {Write-Host -ForegroundColor Red "Write operation failed: $_"}} # User interaction. if (-not $sourcefile) {Write-Host -f cyan "`nUsage: encryptpasswordsmodule sourcefile`n"} Write-Host -f green "`nEnter password used to encrypt the module " -n; $password = Read-Host -AsSecureString encryptmodulefile $sourcefile $password Write-Host -f green "🔐 Module encrypted successfully: " -n; Write-Host -f white "$script:outputpath`n"; $password = $null Write-Host -f white "Do you now want to delete the unencrypted version of the module? " -n; $confirmdelete = Read-Host if ($confirmdelete -match "^[Yy]") {Remove-Item $sourcefile -Force} |