PowerShell: Skripte mit Authenticode signieren
Nachträgliche Änderungen an administrativen Skripten fallen ohne zusätzliche Prüfung nicht unbedingt auf. Eine Authenticode-Signatur verknüpft den Dateiinhalt kryptografisch mit einem Codesignaturzertifikat. PowerShell kann dadurch feststellen, ob ein Skript seit der Signierung verändert wurde und ob das verwendete Zertifikat auf dem jeweiligen System als vertrauenswürdig gilt.
Zum Signieren benötigt PowerShell ein Zertifikat mit dem Verwendungszweck „Code Signing“ und dem zugehörigen privaten Schlüssel. In Unternehmensumgebungen bietet sich dafür ein Zertifikat der internen Public-Key-Infrastruktur oder eines öffentlich vertrauenswürdigen Anbieters an. Für einen lokalen Test lässt sich mit new-selfsignedcertificate ein selbst signiertes Zertifikat im persönlichen Zertifikatsspeicher anlegen:
$cert = New-SelfSignedCertificate ` -Type CodeSigningCert ` -Subject "CN=PowerShell Code Signing" ` -CertStoreLocation "Cert:\CurrentUser\My"
Das zurückgegebene Zertifikatsobjekt lässt sich anschließend direkt an Set-AuthenticodeSignature übergeben:
Set-AuthenticodeSignature ` -FilePath "C:\Scripts\Wartung.ps1" ` -Certificate $cert ` -TimestampServer "http://timestamp.digicert.com"
Bei PowerShell-Skripten fügt das Cmdlet die Signatur als Kommentarblock am Dateiende ein. Jede spätere inhaltliche Änderung macht die Signatur ungültig. Ein Zeitstempel dokumentiert zusätzlich, dass die Signatur während der Gültigkeitsdauer des Zertifikats erzeugt wurde. Dadurch kann sie grundsätzlich auch nach Ablauf des Codesignaturzertifikats überprüfbar bleiben. Set-AuthenticodeSignature steht allerdings nur unter Windows zur Verfügung.
Den Signaturstatus zeigt Get-AuthenticodeSignature an:
Get-AuthenticodeSignature ` -FilePath "C:\Scripts\Wartung.ps1" | Select-Object Status, StatusMessage, SignerCertificate
Valid steht für eine gültige Signatur mit einer auf diesem Rechner vertrauenswürdigen Zertifikatskette. NotSigned kennzeichnet eine nicht signierte Datei, während HashMismatch auf eine Veränderung seit der Signierung hinweist. Weitere Statuswerte können etwa bei abgelaufenen, widerrufenen oder nicht vertrauenswürdigen Zertifikaten auftreten. Das Cmdlet liefert dabei nur Informationen über Signatur und Zertifikat; es beurteilt nicht, ob der ausgeführte Code ungefährlich ist.
Ein selbst signiertes Zertifikat genießen andere Rechner zunächst nicht automatisch als vertrauenswürdig. Für den produktiven Einsatz muss das öffentliche Zertifikat daher über die vorgesehenen Zertifikatsspeicher oder eine zentrale Richtlinie verteilt werden. Der private Schlüssel gehört dagegen ausschließlich auf abgesicherte Signiersysteme: Wer darauf zugreifen kann, kann im Namen des Zertifikatsinhabers eigene Skripte signieren. Microsoft empfiehlt deshalb ausdrücklich einen starken Schutz des privaten Schlüssels.