Private/SecureString/ConvertFrom-SecretSharingSecureString.ps1
|
function ConvertFrom-SecretSharingSecureString { <# .SYNOPSIS Recovers the exact byte array wrapped by ConvertTo-SecretSharingSecureString. .DESCRIPTION Reads each UTF-16 character directly out of unmanaged memory via Marshal.ReadInt16 (rather than materializing an intermediate managed string, which would leave an unzeroable copy of the secret on the managed heap), and zeroes the unmanaged buffer afterward. #> [CmdletBinding()] [OutputType([byte[]], [System.Object[]])] param( [Parameter(Mandatory)] [System.Security.SecureString]$SecureString ) $pointer = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($SecureString) try { $result = [byte[]]::new($SecureString.Length) for ($i = 0; $i -lt $SecureString.Length; $i++) { $charValue = [System.Runtime.InteropServices.Marshal]::ReadInt16($pointer, $i * 2) $result[$i] = [byte]($charValue -band 0xFF) } return , $result } finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($pointer) } } |