6 min read
Sicherheitsrisiken bei cross-platform Encryption mit .NET SecureString
Denkst du, dass dein SecureString sicher ist? Nicht auf allen Plattformen! Entdecke die Risiken der...
PowerShell-Erfolgsrezepte – die Profi-Tipps für effektives Scripting
Denkst du, dass dein SecureString sicher ist? Nicht auf allen Plattformen! Entdecke die Risiken der plattformübergreifenden Datenverschlüsselung mit SecureString in .NET. Lies hier unseren ersten von vier SecureString-Deep Dive Artikeln:
SecureString wurde entwickelt, um den Umgang mit sensiblen Texten (z.B. Passwörtern) zu vereinfachen: Im Hintergrund verwendet .NET's System.Security.SecureString eine starke AES-Verschlüsselung, um sicherzustellen, dass nur der Besitzer eines Strings diesen lesen kann – unabhängig davon, ob in einer Datei gespeichert oder bei einem Angriff in einem "Memo Dump" gefunden.
Leider funktioniert dies unter Windows sehr gut, aber auf anderen Plattformen versagt es unbemerkt. Es ist an der Zeit, in dieser Miniserie einen genaueren Blick darauf zu werfen. Wer sich für plattformübergreifende Lösungen interessiert, findet auf auf Microsoft | Learn eine gute Übersicht über kompatible plattformübergreifende Verschlüsselungen.
Auf Windows-Systemen ist SecureString automatisch geschützt, sodass du es zum Speichern lokaler Passwörter verwenden kannst. Im folgenden Beispiel kannst du Anmeldedaten für drei verschiedene Server eingeben (du kannst auch weitere hinzufügen), die dann in einer XML-Datei serialisiert werden:
$path = "$env:userprofile\mypasswords.xml"
@{
Server1 = Get-Credential -Message 'Enter password for Server 1' -UserName $env:USERNAME
Server2 = Get-Credential -Message 'Enter password for Server 2' -UserName $env:USERNAME
Server3 = Get-Credential -Message 'Enter password for Server 3' -UserName $env:USERNAME
} | Export-Clixml -Path $path
Wenn die XML-Datei in einem Texteditor geöffnet wird, sind die Passwörter verschlüsselt:
<ToString>System.Management.Automation.PSCredential</ToString>
<Props>
<S N="UserName">tobia</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000fca013869c24324fa191f7d1f5e8d46a00000000020000000000106600000001000020000000de26f1058a814b27a481821459eea01f8ad340a87512a6be0c21f871b46e8ee6000000000e8000000002000020000000cc97abd02f4f296d16338711331f1e9893e36da5ba397a3286891b06d329ff6710000000c7f9f9af2a5d3e7b980cab7acc7b22ee400000006dfc7c22382502e9ec47eb0ea28f990807dc336f1d673a06754c9de5a794b077633217176cfa027ee180073bb42965128442c917f40a25d7150d5536e325f82f</SS>
</Props>
Das liegt daran, dass Anmeldeinformationen sensible Informationen im Datentyp SecureString speichern, der automatisch geschützt ist (während der Benutzername im Klartext erscheint, da es sich um einen regulären String handelt).
Das Entschlüsseln der zuvor verschlüsselten Informationen ist genauso transparent.
Wenn die in der obigen XML-Datei gespeicherten Anmeldedaten ausgelesen (und verwendet) werden müssen – z.B. durch ein Skript, das unbeaufsichtigt ausgeführt werden soll und diese Anmeldedaten zum Log-in verwendet – ist der umgekehrte Prozess vollständig transparent:
$path = "$env:userprofile\mypasswords.xml"
$mySecrets = Import-Clixml -Path $path
# Abrufen der gespeicherten Anmeldedaten
$mySecrets.Server1
# Ich bin der Besitzer, also kann ich auch immer den Klartext-String sehen
$mySecrets.Server1.GetNetworkCredential().Password
$mySecrets.Server2
$mySecrets.Server2.GetNetworkCredential().Password
$mySecrets.Server3
$mySecrets.Server3.GetNetworkCredential().Password
Dieser Prozess ist sicher, keine Frage. Schließlich werden nur unter Windows zwei "Geheimnisse" für die AES‑Verschlüsselung verwendet: du und dein PC. Die transparente Entschlüsselung funktioniert ausschließlich für die Identität, die den SecureString verschlüsselt hat, und auch nur auf dem ursprünglichen PC. Andere Personen können die Passwörter aus der XML-Datei nicht entschlüsseln.
Es ist wichtig zu verstehen, dass die zugrunde liegende Verschlüsselung und Entschlüsselung von .NET durchgeführt wird, wenn der Datentyp System.Security.SecureString an einer beliebigen Stelle innerhalb des Codes serialisiert wird:
# Verschlüsselung
$path = Join-Path -Path $env:temp -ChildPath secret.xml
Read-Host -Prompt 'Enter your secret' -AsSecureString | Export-Clixml -Path $path
# Entschlüsselung
$path = Join-Path -Path $env:temp -ChildPath secret.xml
$secureString = Import-Clixml -Path $path
$secureString
Auch hier wird der eingegebene String transparent mit AES verschlüsselt und in die XML-Datei geschrieben:
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$plainText = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
# Allokierten Speicher freigeben
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
$plainText
Beim Importieren der XML-Datei wird der SecureString abgerufen. Da du Eigentümer des Strings bist, kannst du diesen jederzeit wieder in Klartext umwandeln:
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$plainText = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
# Allokierten Speicher freigeben
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
$plainText
Der Hauptzweck von SecureString (auf der Windows-Plattform) ist der Schutz sensibler Informationen; es lassen sich jedoch eine Reihe von Anwendungen ableiten: Da PowerShell ein maskiertes Eingabefeld anzeigt, wenn Sie zur Eingabe eines SecureString aufgefordert werden, können Sie nun problemlos maskierte Eingabefelder implementieren.
function Get-SomeSecret
{
param
(
[SecureString]
[Parameter(Obligatorisch)]
$Secret
)
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secret)
$plainText = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
# Zugewiesenen Speicher freigeben
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
"The user entered: $plainText"
}
Wie du siehst, machen SecureStrings den Umgang mit Secrets (Geheimnissen) überflüssig: Der Verschlüsselungsschlüssel muss nicht bekannt sein (oder übertragen werden). Stattdessen sind dein Computer und du die Schlüssel.
Um zu testen, ob SecureStrings auf deiner Plattform tatsächlich sicher sind, speichere einfach einen SecureString auf eine der abgebildeten Arten in einer XML-Datei. Versuche dann, die Datei als anderer Nutzer oder auf einem anderen Computer zu entschlüsseln. Wenn dieser Vorgang mit einer Ausnahme fehlschlägt, ist dein Geheimnis sicher verschlüsselt. Unter Windows ist dies der Fall.
Bei Nicht-Windows-Plattformen wie Linux und macOS wird die automatische AES-Verschlüsselung von SecureStrings still und leise entfernt. Der gesamte obige Code funktioniert auch dort einwandfrei. SecureString ist nicht AES-verschlüsselt, sondern lediglich codiert. Jeder, der Zugriff auf die XML-Datei erhält, kann das Geheimnis entschlüsseln.
.NET (von PowerShell 7 verwendet) implementiert die Verschlüsselungs-API schlichtweg nicht auf Nicht-Windows-Systemen. Das bedeutet, dass du unter Umständen eine sichere Skriptlösung auf Basis von SecureStrings unter Windows verwendet hast, aber sobald du sie auf eine andere Plattform überträgst, sind deine sensiblen Daten nicht mehr geschützt, auch wenn sie scheinbar weiterhin einwandfrei funktionieren.
Allerdings wurde die automatische AES-Verschlüsselung von SecureStrings auf Nicht-Windows-Plattformen wie Linux und macOS still und leise entfernt. Der gesamte obige Code funktioniert auch dort einwandfrei. Allerdings ist der SecureString nicht AES-verschlüsselt, sondern lediglich kodiert: Jeder, der Zugriff auf die XML-Datei hat, kann das Geheimnis entschlüsseln.
Dies liegt daran, dass .NET (von PowerShell 7 verwendet) die Verschlüsselungs-API nicht auf Nicht-Windows-Systemen implementiert. Der gefährliche Nebeneffekt besteht darin, dass du möglicherweise eine sichere Skriptlösung auf Basis von SecureStrings unter Windows verwendet hast, aber sobald du sie auf eine andere Plattform überträgst, sind deine sensiblen Daten nicht mehr geschützt, auch wenn sie scheinbar weiterhin einwandfrei funktionieren.
Unser erster "Deep Dive" (– SecureString in .NET) hat die Frage beantwortet, wie sicher deine sensiblen Daten plattformübergreifend sind. In den nächsten drei Deep Dives zeigen wir dir weitere Möglichkeiten, die Sicherheit zu verbessern, im nächsten Artikel behandeln wir Alternativen und bewährte Verfahren auf verschiedenen Plattformen.
Entfessele das volle Potenzial von PowerShell mit unserem praktischen Poster. Egal, ob frischer Einsteiger oder erfahrener Profi, dieser Spickzettel ist so konzipiert, dass du schnell die wichtigsten und am häufigsten verwendeten Cmdlets findest.
Das Poster ist zum Download und in Papierform erhältlich.
Nov 18, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Denkst du, dass dein SecureString sicher ist? Nicht auf allen Plattformen! Entdecke die Risiken der...
Nov 26, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Was ist der Unterschied zwischen Kodierung und Verschlüsselung? Dieser Artikel erklärt, welchen Zweck sie erfüllen und...
Nov 26, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Wie gewährleistet Windows die Sicherheit von SecureString? Tauche mit uns im zweiten Artikel noch tiefer in die...
Tobias Weltner und Aleksandar Nikolić haben gemeinsam die Blogpost-Reihe „Tobias&Aleksandars PowerShell-Tipps“ verfasst. Deshalb möchten wir euch beide hier vorstellen:
----------------------------
Aleksandar Nikolić ist ein Microsoft Azure MVP und Mitbegründer von PowerShellMagazine.com, der ultimativen Online-Ressource für PowerShell-Enthusiasten. Mit über 18 Jahren Erfahrung in der Systemadministration ist er ein angesehener Trainer und Redner, der rund um den Globus reist, um sein Wissen und seine Fähigkeiten über Azure, Entra und PowerShell weiterzugeben. Er hat auf IT-Veranstaltungen wie Microsoft Ignite, ESPC, NIC, CloudBrew, NTK und der PowerShell Conference Europe gesprochen.
----------------------------
Tobias ist ein langjähriger Microsoft MVP und war von Anfang an an der Entwicklung von PowerShell beteiligt. Er hat die PowerShell IDE „ISESteroids“ erfunden, zahlreiche Bücher über PowerShell für Microsoft Press und O'Reilly geschrieben, die PowerShell Conference EU (psconf.eu) gegründet und trägt derzeit als Mitglied der „Microsoft Cmdlet Working Group“ zur Weiterentwicklung der PowerShell bei. Tobias gibt sein Wissen als Berater in Projekten und als Trainer in Inhouse-Schulungen für zahlreiche Unternehmen und Agenturen in ganz Europa weiter.