Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistency in results of calling Get-AuthenticodeSignature from PowerShell, often says NotSigned

I have a number of PowerShell files code signed during build.

I'm getting different signature status depending how I call Get-AuthenticodeSignature:

PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature $_.Name }

SignerCertificate                         Status  Path
-----------------                         ------  ----
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   CreateApplication.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   DeleteApplication.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   ProvisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid   UpdateParameters.ps1

Everything looks good. But here's the results when I ry to validate the files using either binary content:

PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature -Content ([System.IO.File]::ReadAllBytes($_.FullName)) -SourcePathOrExtension $_.Name }

SignerCertificate                         Status     Path
-----------------                         ------     ----
                                          NotSigned  CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid      CreateApplication.ps1
                                          NotSigned  DeleteApplication.ps1
                                          NotSigned  ProvisionApplicationType.ps1
                                          NotSigned  UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid      UpdateParameters.ps1

or string content:

PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature -Content ([System.Text.Encoding]::ASCII.GetBytes([System.IO.File]::ReadAllText($_.FullName))) -SourcePathOrExtension $_.Name }

SignerCertificate                         Status      Path
-----------------                         ------      ----
                                          NotSigned   CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid       CreateApplication.ps1
                                          NotSigned   DeleteApplication.ps1
                                          NotSigned   ProvisionApplicationType.ps1
                                          NotSigned   UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324  Valid       UpdateParameters.ps1

I spent a week already on this and cannot wrap my head around what's causing this discrepancy/inconsistency. And I do have to make it working as my application ('client') receives the scripts from a service ('server') as a string and has to validate the validity of the content.

like image 995
abatishchev Avatar asked Nov 18 '25 10:11

abatishchev


1 Answers

Update: as of pwsh 7.4.0, this bug has been fixed (fix PR here). However, many people will be using prior versions for a while, and 5.1 is stuck with this bug, so the workarounds below will remain valuable.


Sadly, Get-AuthenticodeSignature -Content only recognizes byte arrays if they represent "Unicode" (UTF-16LE) encoded characters - any other encoding is misrepresented as NotSigned in the output.
See this GitHub issue.

The implication of your symptoms is that only scripts CreateApplication.ps1 and UpdateParameters.ps1 are UTF-16LE-encoded.

If you wanted to use -Content with all of your scripts:

  • either: transcode all your script files to UTF-16LE (save them with that encoding).
  • or: pass expression ([Text.Encoding]::Unicode.GetPreamble() +[Text.Encoding]::Unicode.GetBytes((Get-Content -Raw $_.FullName))) to -Content, i.e., manually convert the file content to UTF-16LE bytes; note the need to explicitly prepend the BOM (preamble)).

As you've observed, using (implied) parameter -FilePath - i.e. passing a file path and letting Get-AuthenticodeSignature itself read its contents - is not subject to this encoding restriction - as long as PowerShell can infer the script file's encoding per the usual rules, signature verification succeeds.

like image 198
mklement0 Avatar answered Nov 21 '25 00:11

mklement0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!