| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- $ErrorActionPreference = 'Stop'
- Add-Type -AssemblyName System.Security
- function Save-ProtectedConfig {
- param([Parameter(Mandatory = $true)][object]$Config, [Parameter(Mandatory = $true)][string]$Path)
- $plainBytes = $null
- $cipherBytes = $null
- try {
- $json = $Config | ConvertTo-Json -Depth 8 -Compress
- $plainBytes = [Text.Encoding]::UTF8.GetBytes($json)
- $cipherBytes = [Security.Cryptography.ProtectedData]::Protect($plainBytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
- $directory = Split-Path -Parent $Path
- New-Item -ItemType Directory -Force -Path $directory | Out-Null
- $utf8NoBom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false
- [IO.File]::WriteAllText($Path, [Convert]::ToBase64String($cipherBytes), $utf8NoBom)
- }
- finally {
- if ($plainBytes) { [Array]::Clear($plainBytes, 0, $plainBytes.Length) }
- if ($cipherBytes) { [Array]::Clear($cipherBytes, 0, $cipherBytes.Length) }
- }
- }
- function Get-ProtectedConfig {
- param([Parameter(Mandatory = $true)][string]$Path)
- if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { throw "Protected configuration not found: $Path" }
- $cipherBytes = $null
- $plainBytes = $null
- try {
- $cipherBytes = [Convert]::FromBase64String(([IO.File]::ReadAllText($Path)).Trim())
- $plainBytes = [Security.Cryptography.ProtectedData]::Unprotect($cipherBytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
- return ([Text.Encoding]::UTF8.GetString($plainBytes) | ConvertFrom-Json)
- }
- catch {
- throw 'Protected configuration cannot be decrypted by the current Windows user or is invalid.'
- }
- finally {
- if ($cipherBytes) { [Array]::Clear($cipherBytes, 0, $cipherBytes.Length) }
- if ($plainBytes) { [Array]::Clear($plainBytes, 0, $plainBytes.Length) }
- }
- }
- function Get-Sha256Hex {
- param([Parameter(Mandatory = $true)][byte[]]$Bytes)
- $sha = [Security.Cryptography.SHA256]::Create()
- try { return ([BitConverter]::ToString($sha.ComputeHash($Bytes))).Replace('-', '').ToLowerInvariant() }
- finally { $sha.Dispose() }
- }
- function New-SubmitKey {
- $bytes = New-Object byte[] 32
- [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
- try { return ([Convert]::ToBase64String($bytes)).TrimEnd('=').Replace('+', '-').Replace('/', '_') }
- finally { [Array]::Clear($bytes, 0, $bytes.Length) }
- }
- function Write-HttpJson {
- param([Parameter(Mandatory = $true)]$Context, [Parameter(Mandatory = $true)][int]$StatusCode, [Parameter(Mandatory = $true)][object]$Body)
- $bytes = [Text.Encoding]::UTF8.GetBytes(($Body | ConvertTo-Json -Compress -Depth 6))
- try {
- $Context.Response.StatusCode = $StatusCode
- $Context.Response.ContentType = 'application/json; charset=utf-8'
- $Context.Response.ContentLength64 = $bytes.Length
- $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
- }
- finally {
- if ($bytes) { [Array]::Clear($bytes, 0, $bytes.Length) }
- $Context.Response.Close()
- }
- }
|