Code signing question

57 views
Skip to first unread message

Mike Leone

unread,
Feb 21, 2024, 3:51:02 PM2/21/24
to NTPowershell Mailing List
Hello! I am starting to my scripts. I have issued myself a code signing certificate from our AD CA, and I can use it to sign scripts.

> $Cert=(dir cert:currentuser\my\ -CodeSigningCert)

Subject      : CN=(Privileged) Michael Leone
Issuer       : CN=<Intermediate CA
Thumbprint   : <thumbprint>
FriendlyName :
NotBefore    : 2/21/2024 2:45:43 PM
NotAfter     : 2/20/2026 2:45:43 PM
Extensions   : {1.3.6.1.4.1.311.21.7 (Certificate Template Information), 2.5.29.37 (Enhanced Key Usage), 2.5.29.15 (Key Usage), 1.3.6.1.4.1.311.21.10 (Application
               Policies)...}

> Set-AuthenticodeSignature .\Get-AllClusters.PS1 $Cert


SignerCertificate  Status             Path
-----------------  ------             ----
<thumbprint>       Valid        Get-AllClusters.PS1

My question:rather than pulling my cert from the store of the machine I am running from, I want to have the cert in a file, and sign it that way (i.e., set-authenticodesignature -certificate my-cert-file.pfx), so I can sign a script even if I am not on my usual (privileged workstation). 

I read the online help that says the private key must be included in the PFX file. So I exported my cert that way. But exporting that way seems to require a password to be put on the cert file, which would make it a bit hard to automate the signing process ..

Am I just missing a concept, or is there a better way to export, so I won't need to enter the password in order to sign the script? 

> $MyCert = Get-PfxCertificate  C:\Certificates\MJL-Priv-CodeSigning-Cert.pfx
Enter password: **********

> Set-AuthenticodeSignature .\Add-RDS-Users.PS1 -Certificate $MyCert


SignerCertificate                Status                    Path
-----------------                         ------                     ----
<thumbprint>                         Valid                    Add-RDS-Users.PS1

--

Mike. Leone, <mailto:tur...@mike-leone.com>

PGP Fingerprint: 0AA8 DC47 CB63 AE3F C739 6BF9 9AB4 1EF6 5AA5 BCDF
Photo Gallery: <http://www.flickr.com/photos/mikeleonephotos>

Solodow, Damien

unread,
Feb 21, 2024, 3:57:34 PM2/21/24
to ntpowe...@googlegroups.com

Export-PfxCertificate has a -ProtectTo you can use instead of -Password; this won’t need a password, it’s tied to the AD user/group.

 

So if you do:

$cert | Export-pfxcertificate -ProtectTo yourUsername

 

yourUsername will be able to open that cert without entering a password.

 

Gaylor Electric logo

Gaylor Electric Website

Facebook

Twitter

LinkedIn

Damien Solodow

IS Senior Systems Engineer

Gaylor Electric, Inc.

10405 Crosspoint Blvd

Indianapolis

IN

46256

O: 317.815.3103 

M: 317.506.8521

317.759.0077 emergency IS support

--
You received this message because you are subscribed to the Google Groups "ntpowershell" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ntpowershell...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ntpowershell/CAHBr%2B%2BjAABgFB7FviKu8_tMAKv9RmyaxDHcEbaaBTTgP5GiyQw%40mail.gmail.com.

Michael B. Smith

unread,
Feb 21, 2024, 3:58:59 PM2/21/24
to ntpowe...@googlegroups.com

You can also import the PFX file on a “signing” workstation where it would also be available.

Mike Leone

unread,
Feb 21, 2024, 7:16:00 PM2/21/24
to ntpowe...@googlegroups.com


On Wed, Feb 21, 2024 at 3:59 PM Michael B. Smith <mic...@smithcons.com> wrote:

You can also import the PFX file on a “signing” workstation where it would also be available.


I was hoping you'd comment. :-)

My most immediate need (not my project) is that we are going to be implementing BitLocker. And my security guy wants to enable it on workstations, doing so by running a PowerShell script.  This to be pushed out using Ivanti.

Me, I don't know anything about BitLocker, but I'm guessing I'll be learning quickly ..

Anyway, am I correct that if we have a PS script, then the cert we use to sign the script must also be pushed to the Trusted Publisher store on whatever host(s)/workstations the script executes on? (Easily enough done using a GPO).

Or can the "enable BitLocker" cmdlet, whatever it is, accept a -ComputerName parameter, meaning that the script will actually execute not on the workstations themselves, but on my Ivanti server?

That would determine whether I push code signing certificates to walk workstations, or just servers ... There would be probably at most 3 certs, as only 3 of us would be script writers.

I'm guessing individual certs are better than just 1 organizational level code signing certificate? With 3, at least you know who in particular signed it.

Thanks for any help.

Michael B. Smith

unread,
Feb 22, 2024, 9:40:52 AM2/22/24
to ntpowe...@googlegroups.com

>> Anyway, am I correct that if we have a PS script, then the cert we use to sign the

>> script must also be pushed to the Trusted Publisher store on whatever host(s)/workstations

>>  the script executes on? (Easily enough done using a GPO).

 

If it’s a self-signed cert, then yes. If it’s signed by an enterprise CA, then it needs to be the root of the enterprise CA (which is what I believe you wrote you are using).

 

But your scripts don’t have to be signed (yes, it’s a best practice – I’m not suggesting otherwise). You can copy them over to a target device and then run them with “executionpolicy bypass”.

 

Neither Enable-BitLocker or manage-bde accept a computername parameter. They must be executed locally.

 

If you have Intune – it’s easier than dealing with either of the command-line options IMO.

 

If you are doing code-signing for internal consumption, then it definitely should be per-user.

Mike Leone

unread,
Feb 22, 2024, 11:19:29 AM2/22/24
to ntpowe...@googlegroups.com
On Thu, Feb 22, 2024 at 9:40 AM Michael B. Smith <mic...@smithcons.com> wrote:

>> Anyway, am I correct that if we have a PS script, then the cert we use to sign the

>> script must also be pushed to the Trusted Publisher store on whatever host(s)/workstations

>>  the script executes on? (Easily enough done using a GPO).

 

If it’s a self-signed cert, then yes. If it’s signed by an enterprise CA, then it needs to be the root of the enterprise CA (which is what I believe you wrote you are using).


Enterprise CA. Enterprise root and intermediate CA certs are already pushed via GPO to all workstations and servers,, as Trusted Root and Intermediate CA..

So do I need to be the rott (and/or intermediate) certs into Trusted Publisher, as well? And not the individual code signing certs?
 

But your scripts don’t have to be signed (yes, it’s a best practice – I’m not suggesting otherwise). You can copy them over to a target device and then run them with “executionpolicy bypass”.


That is what I have been doing. We have a new IT Security guy (first one we've ever had), so I figured we should start trying to do more Best Practices (especially about security LOL), and signing scripts is one. So I figured we'd try and start ...
 

Neither Enable-BitLocker or manage-bde accept a computername parameter. They must be executed locally.


Ah. OK. So I need the Enterprise CA and Intermediate certs in the Trusted Publisher stores of all servers and workstations?
 

If you have Intune – it’s easier than dealing with either of the command-line options IMO.


Unfortunately not, no.
 

If you are doing code-signing for internal consumption, then it definitely should be per-user.


Internal use, yes. OK, so I have my code signing cert, I'll get the other 2 guys to request ones for themselves (using their privileged accounts). I have these defined as a 2 year expiration, you think that's long enough?

If the script expires, I know I will have to "Request new cert with same key", and update the cert store. What happens if one of us leaves?  I presume we just have to re-sign the script with a current cert from an existing employee, and it will still continue to work? Scripts don't execute with expired certs, right?

Reply all
Reply to author
Forward
0 new messages