Are you able to use PtrToStringAuto to decrypt a secure string in Powershell 7 on macOS?

Note that [securestring] is not recommended for new code anymore.

While on Windows secure strings offer limited protection – by storing the string encrypted in memory – via the DPAPI – and by shortening the window during which the plain-text representation is held in memory, no encryption at all is used on Unix-like platforms.[1]


The only way around this I have found is to use PtrToStringBSTR.

That is not only a way around the problem, PtrToStringBSTR is the method that should have been used to begin with, given that the input string is a BSTR.[2]

Do note that converting a secure string to and from a regular [string] instance defeats the very purpose of using [securestring] to begin with: you’ll end up with a plain-text representation of your sensitive data in your process’ memory whose lifetime you cannot control.

If you really want to do this, a simpler, cross-platform-compatible approach is:

[System.Net.NetworkCredential]::new('dummy', $string).Password

[1] This is especially problematic when you save a secure string in a file, via ConvertFrom-SecureString or Export-CliXml – see this answer.

[2] The Auto in PtrToStringAuto() means that the unmanaged input string is assumed to use a platform-appropriate character encoding, whereas BSTR is
a “Unicode” (UTF-16) string on all platforms. On Windows, an unmanaged string is assumed to have UTF-16 encoding (which is why the code works), whereas on Unix-like platforms it is UTF-8 since .NET Core 3.0 (PowerShell [Core] 7.0 is based on .NET Core 3.1), which explains your symptoms: the NUL chars. in the BSTR instance’s UTF-16 code units are interpreted as characters in their own right when (mis)interpreted as UTF-8. Note that .NET Core 2.x (which is what PowerShell [Core] 6.x is based on) (inappropriately) defaulted to UTF-16, which this PR fixed, amounting to a breaking change.

Leave a Comment