Skip to the main content.

PowerShell-Erfolgsrezepte – die Profi-Tipps für effektives Scripting

Passwortschutz mit PowerShell: AES-Verschlüsselung leicht gemacht

Lerne, wie du AES (Advanced Encryption Standard) nutzt, um deine Daten vor unbefugtem Zugriff zu sichern. Wir erklären dir die wichtigsten Cmdlets, wie du Verschlüsselungsschlüssel erstellst und deine Passwörter in eine verschlüsselte Datei speicherst.


Mit diesem Wissen bist du bestens ausgerüstet, um Passwörter zu verschlüsseln und die Sicherheit deiner IT-Umgebung zu erhöhen. Entdecke jetzt, wie einfach es ist, mit PowerShell ein Passwort zu encrypten!

Wir haben schon gezeigt, dass SecureStrings (und die zugrunde liegende DPAPI) Geheimnisse stark mit AES verschlüsseln und entschlüsseln können, aber diese Funktionalität auf Windows-Betriebssysteme beschränkt ist. Wer ein anderes Betriebssystem wie Linux oder macOS verwendet, hat standardmäßig nur Zugriff auf die unsichere Verschlüsselung.

In diesem letzten Teil werden wir alle besprochenen Techniken zusammenfassen, so dass du Geheimnisse direkt mit den Rohverschlüsselungsbibliotheken verschlüsseln kannst, die auch von DPAPI verwendet werden. Dieser Ansatz bietet die maximale Kontrolle über den Verschlüsselungsprozess.

Auf Windows-Betriebssystemen unterstützt Microsoft alle unten beschriebenen Techniken. Auf anderen Plattformen unterstützt .NET jedoch noch nicht alles. Diese Einschränkung erklärt, warum SecureStrings derzeit auf Nicht-Windows-Plattformen nicht verschlüsselt werden. Ob die unten verwendeten APIs auf Ihrer spezifischen Plattform implementiert und verfügbar sind, liegt außerhalb des Rahmens dieses Artikels.

 

AES-Verschlüsselung – eigene Befehle

Um die symmetrische AES-Verschlüsselung besser kennenlernen und verstehen zu können, listen wir hier einige Hilfsfunktionen. Führen Sie sie einfach in PowerShell aus, um sie zu verwenden:


function New-AesManagedObject 
{
  param
  (
    # geheimer Schlüssel; er kann eine base64-kodierte Zeichenkette oder ein Byte-Array sein
    [Objekt]
    $Key = $null,

    # Initialisierungsvektor (IV), ein Stück Zufallsdaten;     # es kann eine base64-kodierte Zeichenkette oder ein Byte-Array sein
    [Objekt]
    $RandomData = $null,

    [ValidateSet(128,192,256)]
    [int]
    $KeySize = 256
  )
  $aesManaged = [System.Security.Cryptography.AesManaged]::new()
  $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
  $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
  $aesManaged.BlockSize = 128
  $aesManaged.KeySize = $KeySize
  
  # wenn zufällige Daten übermittelt wurden..
  if ($RandomData) 
  {
    # ...wenn es ein String war, konvertiere ihn zurück in Bytes
    if ($RandomData -is [String]) 
    {
      Write-Verbose "Random Initialization Vector (IV) submitted: $RandomData"
      $RandomData = [System.Convert]::FromBase64String($RandomData)
    }
    
    Write-Verbose "Random Initialization Vector (IV) submitted: $RandomData"
    $aesManaged.IV = $RandomData
  }
  
  # wenn ein Schlüssel übermittelt wurde...
  if ($key)
  {
    # wenn es ein String war, konvertiere ihn zurück in Bytes
    if ($key -is [string]) 
    {
      Write-Verbose "Key submitted: $Key"
      $Key = [System.Convert]::FromBase64String($Key)
    }

    Write-Verbose "Key submitted: $Key"
    $aesManaged.Key = $Key
  }

  $aesManaged
}

function New-AesKey 
{
  <#
      .SYNOPSIS
      Erzeugt einen neuen AES-Schlüssel und gibt ihn als base64-kodierten String zurück

      .BEISPIEL
      New-AesKey
      Gibt einen neuen AES-Schlüssel im base64-String-Format zurück
  #>
  param
  (
    [ValidateSet(128,192,256)]
    [int]
    $KeySize = 256
  )

  $aesManaged = New-AesManagedObject @PSBoundParameters
  $aesManaged.GenerateKey()
  [Convert]::ToBase64String($aesManaged.Key)
}

function Protect-String 
{    
  param
  (
    [Parameter(Mandatory)]
    [String]
    $PlainText,

    [Parameter(Mandatory)]
    [String]
    $Key,

    [int]
    $KeySize = 256
  )
  $bytes = [System.Text.Encoding]::UTF8.GetBytes($PlainText)
  $null = $PSBoundParameters.Remove('PlainText')
  $aesManaged = New-AesManagedObject @PSBoundParameters
  $encryptor = $aesManaged.CreateEncryptor()
  $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
  [byte[]]$fullData = $aesManaged.IV + $encryptedData
  $aesManaged.Dispose()
  [Convert]::ToBase64String($fullData)
}

function Unprotect-String 
{
  param
  (
    [Parameter(Mandatory)]
    [String]
    $EncryptedString,

    [Parameter(Obligatorisch)]
    [String]
    $Key,

    [int]
    $KeySize = 256
  )
  $bytes = [System.Convert]::FromBase64String($EncryptedString)
  $randomData = $bytes[0..15]
  $aesManaged = New-AesManagedObject -Key $key -RandomData $randomData -KeySize $KeySize 
  $decryptor = $aesManaged.CreateDecryptor()
  $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16)
  $aesManaged.Dispose()
  [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)

 

Schlüssel zur Verschlüsselung

Die AES-Verschlüsselung ist eine symmetrische Verschlüsselungsmethode, d.h. Sie verwenden denselben Schlüssel für die Ver- und Entschlüsselung. Der Grad der Sicherheit wird durch die Länge des geheimen Schlüssels bestimmt, der eine der unterstützten Längen haben muss: 128 Bit, 256 Bit oder mehr.



$key128 = New-AesKey -KeySize 128
$key256 = New-AesKey -KeySize 256

$key128
$key256 

So sehen die Schlüssel aus:

kX/Oi8KLqtIpPQJhge9LSQ==
8BiDjKQEmhXHUcuUM7SwgeE0fRjbuZdI+Ix+jT4a7HE=

Jedes Mal, wenn du New-AesKey ausführst, erhältst du einen neuen und eindeutigen Schlüssel. Beachte, dass die Schlüssel je nach Anzahl der angeforderten Bits unterschiedliche Längen haben können.

 

Secrets verschlüsseln

Mit deinen AES-Schlüsseln können nun sensible Informationen verschlüsselt werden:



$AESencrypted128 = Protect-String -PlainText 'Hello World 123' -Key $key128
$AESencrypted256 = Protect-String -PlainText 'Hallo Welt 123' -Schlüssel $key256
$AESencrypted128
$AESencrypted256 

 

Die verschlüsselten Informationen sehen in etwa so aus:

gpmy1EE0e/Bv55VIR2N6yJMGzXEjGvS07hxiTueEJM=
cRnS66rW/rfHORJ3mZq2R+LnYvGqQZ+0b33bm9WO6TQ=

Beachte, dass die verschlüsselten Informationen unabhängig von der Anzahl der Bits in deinem geheimen Schlüssel die gleiche Länge haben. Die Länge der verschlüsselten Information hängt allein von der Länge deines Textes ab.

 

Secrets entschlüsseln

Um deine Secrets zu entschlüsseln, benötigst du denselben geheimen Schlüssel, den du für die Verschlüsselung verwendet hast. Da es sich um eine einfache symmetrische Verschlüsselung handelt, wirst du auf die typischen Herausforderungen stoßen, die mit dem sicheren Austausch des geheimen Schlüssels verbunden sind:



[PSCustomObject]@{
  "OK1" = Unprotect-String -EncryptedString $AESencrypted128 -Key $key128
  "Fail (Key Mismatch1)" = Unprotect-String -EncryptedString $AESencrypted128 -Key $key256
  "Fail (Key Mismatch2)" = Unprotect-String -EncryptedString $AESencrypted256 -Key $key128
  "OK2" = Unprotect-String -EncryptedString $AESencrypted256 -Key $key256

 

Das Ergebnis zeigt, dass du die Informationen nur mit dem richtigen geheimen Schlüssel entschlüsseln kannst. Wenn du den falschen Schlüssel verwendest, erhältst du keine Exception, sondern einen verstümmelten Text. Dieses Verhalten ist vom Standpunkt der Sicherheit aus gesehen von Vorteil, da es einen Angreifer daran hindert, Exceptions zum Testen von Kennwörtern zu verwenden:

Hello world mismatch wrong secret key

 

Hier schließt sich der Kreis, und diese Serie kommt zu einem Ende:

  • SecureStrings verwendet die gleiche AES-Verschlüsselung beim Speichern oder Serialisieren, aber diese Funktionalität ist nur auf Windows beschränkt (was sehr sicher ist).
  • DPAPI (Data Protection API) verwaltet den geheimen Schlüsselaustausch, indem es Ihren PC und optional Ihre Identität als geheimen Schlüssel für die Ver- und Entschlüsselung verwendet (nur unter Windows).
  • Der verschlüsselte SecureString wird dann hex-encodiert und kann in einer Datei gespeichert werden. Dies geschieht, wenn Sie Export-Clixml verwenden, um einen SecureString oder einen PSCredential (der einen SecureString enthält) zu serialisieren.
  • Auf Nicht-Windows-Systemen, wo DPAPI nicht verfügbar ist, überspringen SecureStrings den Verschlüsselungsteil und werden einfach kodiert - dies ist höchst unsicher.

Du kannst jede dieser Techniken direkt anwenden und deine eigenen Lösungen entwickeln. In dieser Artikelserie haben wir Codebeispiele für alle Szenarien bereitgestellt:

  • Einfache eingebaute Lösung:
    Verwendung von SecureStrings, um allgemeine Geheimnisse (wie Passwörter) aufzubewahren.
  • Wiederverwendung der eingebauten einfachen Verschlüsselung:
    Direkter Zugriff auf DPAPI zum Ver- und Entschlüsseln einfacher Geheimnisse ohne die Notwendigkeit eines geheimen Schlüsselaustauschs.
  • Speichern von Binärdateien als Strings:
    Kodieren von Binärinformationen (wie verschlüsselte Geheimnisse sowie andere Binärdaten wie Bilder oder DLLs) zur Speicherung in Strings und Textdateien.
  • Symmetrische AES-Verschlüsselung:
    Schnelle und effiziente Verschlüsselung großer Datenmengen auf sichere Weise.

Das Einzige, was jetzt noch fehlt, ist der geheime Schlüsselaustausch, der erforderlich ist, um den symmetrischen AES-Schlüssel vom Sender zum Empfänger zu übertragen. Wir werden diesen Teil nicht behandeln, da er bereits in die PowerShell eingebaut ist und recht einfach ist. Schauen Sie sich einfach Protect-CmsMessage und Unprotect-CmsMessage an: Diese Cmdlets erleichtern den asymmetrischen Schlüsselaustausch und ermöglichen eine zertifikatsbasierte Übertragung des geheimen AES-Schlüssels an die Partei, die Ihre Daten entschlüsseln muss.

 

SecureStrings – alle Artikel im Überblick

 

 

Good2know

Dein ultimativer PowerShell-Spickzettel

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.

PowerShell Poster 2023

Hol dir hier dein Poster!

 

 

Weiterführende Links 

 

Zusammenhängende Posts

4 min read

Objekte in PowerShell: So bringst du Struktur in deine Skripte

Schluss mit unübersichtlichem Code! Entdecke, wie du in PowerShell Objekte erstellst, geordnete Hash-Tabellen nutzt und...

5 min read

PowerShell-Skripte zur Validierung und Transformation von Daten

Du hast genug von versteckten Fehlern in PowerShell-Skripten? Entdecke, wie Validierungs- und Transformationsattribute...

4 min read

Setze auf die PowerShell-Pipeline

Du willst deine PowerShell-Skripte schneller und flexibler gestalten? Erfahre hier, wie du die Pipeline mit...

Über den Autor: