6 min read
Kodierung vs. Verschlüsselung: Was schützt wirklich?
Was ist der Unterschied zwischen Kodierung und Verschlüsselung? Dieser Artikel erklärt, welchen Zweck sie erfüllen und...
PowerShell-Erfolgsrezepte – die Profi-Tipps für effektives Scripting
Was ist der Unterschied zwischen Kodierung und Verschlüsselung? Dieser Artikel erklärt, welchen Zweck sie erfüllen und wie sie die Sicherheit erhöhen. Die Verschlüsselung wird in erster Linie zur Übertragung von Daten verwendet, während die Verschlüsselung Daten vor unbefugtem Zugriff schützt. PowerShell bietet Tools für beides – der Schlüssel zum Erfolg ist die Wahl der richtigen Methode für das jeweilige Szenario.
In den vorherigen Teilen haben wir untersucht, wie SecureStrings ver- und entschlüsselt werden und wie man direkt auf die DPAPI (Data Protection API) zugreift, um Geheimnisse sicher zu ver- und entschlüsseln. DPAPI ist jedoch nur auf Windows-Betriebssystemen verfügbar, weshalb SecureStrings auf Nicht-Windows-Plattformen nicht mehr als "sicher" gelten.
In diesem Teil werden wir untersuchen, was mit SecureStrings auf Nicht-Windows-Plattformen geschieht und Verschlüsselung mit Verschlüsselung vergleichen.
Die Verschlüsselung erfordert zum Entschlüsseln ein Geheimnis, das einen unbefugten Zugriff verhindert. Die Verschlüsselung hingegen erfordert kein Geheimnis und ist einfach eine Möglichkeit, Daten zu verschleiern (unlesbar zu machen) oder komplexe Binärdaten in einem robusten String-Format zu speichern. Aus diesem Grund wird die Kodierung in der Regel verwendet, um binäre Daten wie Bilder, Audiodateien oder DLLs in Skripte einzubetten. Überraschenderweise werden sensible Daten wie SecureStrings auf Nicht-Windows-Plattformen verschlüsselt (und nicht verschlüsselt).
Sie können jede Art von Daten verschlüsseln, und das Ergebnis ist immer eine Zeichenfolge. Hier ist ein Beispiel für die Kodierung eines PowerShell-Skriptblocks:
$command = {
Get-ChildItem -Path $env:windir -Recurse -Filter *.ps1 -File -ErrorAction Ignore
}
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand
Das Ergebnis sieht dann etwa so aus:
DQAKACAAIAAgACAARwBlAHQALQBDAGgAaQBsAGQASQB0AGUAbQAgAC0AUABhAHQAaAAgACQAZQBuAHYAOgB3AGkAbgBkAGkAcgAgAC0AUgBlAGMAdQByAHMAZQAgAC0ARgBpAGwAdABlAHIAAqAC4AcABzADEAIAAtAEYAaQBsAGUAIAAtAEUAcgByAG8AcgBBAGMAdABpAG8AbgAgAEkAZwBuAG8AcgBlAA0ACgA=
Diese Zeichenkette kann dann von jedem entschlüsselt werden; es ist kein spezielles Geheimnis erforderlich. PowerShell unterstützt diese Art der Kodierung beispielsweise durch den Parameter -EncodedCommand, mit dem Sie kodierten Code wie folgt ausführen können:
Wenn Sie dies ausführen, führt PowerShell den ursprünglichen verschlüsselten Skriptblock aus und beginnt, alle PowerShell-Skripte, die es in Ihrem Windows-Ordner finden kann, zu entladen.
Dieses Beispiel veranschaulicht die typische Verwendung von Kodierung im Vergleich zur Verschlüsselung: das Einbetten von binären oder anderweitig komplexen Daten in Zeichenketten. Die Verschlüsselung ist nicht dazu gedacht, sensible Daten zu schützen, was es etwas überraschend macht, dass Verschlüsselung und nicht Verschlüsselung gewählt wurde, um SecureStrings auf Nicht-Windows-Plattformen zu "schützen.
Im folgenden Beispiel wird eine binäre PNG-Bilddatei gelesen und in eine verschlüsselte Zeichenfolge umgewandelt. Diese Zeichenkette wird dann in eine kleine HTML-Datei eingefügt, so dass der Webbrowser das Bild anzeigt, wenn jemand diese Datei öffnet - ohne dass die binäre Bilddatei aufbewahrt werden muss.
# für PNG-Dateien - ändere den Bildtyp in GIF, JPG oder einen anderen Bildtyp
$ImageType = 'png'
# stelle sicher, dass dies auf eine echte Bilddatei des oben definierten Bildtyps verweist
$ImagePath = "C:\musterbild.$ImageType"
# Bilddatei als Byte-Array lesen
$imageBytes = Get-Content -Path $ImagePath -Encoding Byte -Raw
# Bytes in kodierte Zeichenkette umwandeln
$encodedString = [Convert]::ToBase64String($ImageBytes)
# String zur Überprüfung ausgeben
$encodedString
# etwas mit der kodierten Zeichenkette machen, d.h. sie in HTML einbetten
$htmlPath = Join-Path -Path $env:temp -ChildPath 'testhtml.html'
$htmlString = "<IMG SRC=""data:image/$imageType;base64,$encodedString"">"
Set-Content -Path $htmlPath -Value $htmlString -Encoding UTF8
Start-Process -FilePath $htmlPath
# Ausgabe des generierten HTML zur Überprüfung
$htmlString
Beim Enkodieren geht es, wie oben dargestellt, immer um die Umwandlung von Binärdaten (Byte-Arrays) in Zeichenketten. Binärdateien - wie Bilder oder DLLs - können mit Get-Content leicht in Byte-Arrays umgewandelt werden, wie zuvor gezeigt.
Bei der Kodierung von reinen Strings geht man nach dem gleichen Verfahren vor. Allerdings müssen Sie die Zeichenfolge zunächst in ein Byte-Array umwandeln. Denken Sie daran: Die Kodierung erfordert Bytes und kümmert sich nicht darum, was sie darstellen. Alles, was in ein Byte-Array umgewandelt werden kann, kann kodiert werden.
Für Text gibt es mehrere Möglichkeiten, ihn in ein Byte-Array zu konvertieren, darunter ASCII, UTF7, UTF8 und Unicode.
Stellen Sie sicher, dass die Empfängerseite (die Seite, die den kodierten Text dekodiert) die gleiche Textkodierung verwendet; andernfalls kann der dekodierte Text aufgrund einer falschen Byte-zu-Zeichen-Zuordnung verzerrt oder unlesbar erscheinen.
Beim ersten Beispiel, bei dem PowerShell einen verschlüsselten Befehl ausführte, wurde erwartet, dass der verschlüsselte Befehl Unicode-Text ist. Aus diesem Grund verwendete das Kodierungsskript die folgende Zeile:
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
Da Unicode zwei Bytes pro Zeichen benötigt, führt dieser Ansatz zu relativ großen Zeichenketten. Eine effizientere Option ist UTF7, die die Stringgröße um die Hälfte reduziert. Für Ihre eigenen Zwecke können Sie die Textkodierung wählen, die Ihren Bedürfnissen am besten entspricht, solange dieselbe Kodierung sowohl bei der Kodierung als auch bei der Dekodierung verwendet wird. Hier ein Beispiel mit UTF7 anstelle von Unicode:
# Kodierung mit UTF7
$text = 'Hallo, hier ist mein Originaltext. Er könnte beliebig lang sein...'
# Text in Bytes umwandeln
$bytes = [System.Text.Encoding]::UTF7.GetBytes($text)
# Bytes in base64-String konvertieren
$encoded = [Convert]::ToBase64String($bytes)
$encoded
# Dekodierung mit UTF7
$someEncodedText = 'SGVsbG8sIGhlcmUgaXMgbXkgb3JpZ2luYWwgdGV4dC4gSXQgY291bGQgYmUgYW55IGxlbmd0aC4uLg=='
# base64-String in Bytes umwandeln
$bytes = [Convert]::FromBase64String($someEncodedText)
# konvertiert Bytes in kodierten Text (UTF7)
$plaintext = [System.Text.Encoding]::UTF7.GetString($bytes)
$plaintext
Base64 ist weder eine Kodierung noch eine Verschlüsselung; es ist einfach eine Möglichkeit, ein Byte-Array als String darzustellen. Aus diesem Grund wird es häufig zur Speicherung kodierter Informationen verwendet. Sie können Base64 jedoch mit jeder Art von Byte-Array verwenden:
$someArray = 1,2,3,10,12,13
$someArrayString = [Convert]::ToBase64String($someArray)
$someArrayString
# mit einem Base64-Text beginnen
$reverseTest = 'AQIDCgwN'
# liefert die Zahlen zurück
$array = [Convert]::FromBase64String($reverseTest)
$array
Wenn Base64 verwendet wird, um binäre Informationen als Zeichenkette zu speichern, sind die Standardmethoden der System-API nutzbar, wie oben gezeigt. Binäre Informationen können jedoch in jedem beliebigen Format gespeichert werden, was notwendig sein kann, wenn mit Daten interagiert werden soll, die von anderen Personen generiert wurden.
Zum Beispiel werden SecureStrings nicht als Base64-Strings gespeichert, sondern in einem Hex-Format. Hier ist das Beispiel von oben, das dasselbe benutzerdefinierte Hex-Format verwendet, das SecureStrings verwenden, wenn sie in einer Datei gespeichert werden:
$someArray = 1,2,3,10,12,13
# In Hex-String konvertieren und das Format in das von SecureStrings verwendete Format ändern (Kleinbuchstaben, keine Bindestriche)
$hexEncodedString = [System.BitConverter]::ToString($someArray).Replace('-','').ToLower()
$hexEncodedString
# mit hex-kodiertem String beginnen
$hexEncodedString = '0102030a0c0d'
# liefert die Zahlen zurück
$bytes = for ($i = 0; $i -lt $hexEncodedString.Length; $i += 2) {
[Convert]::ToByte($hexEncodedString.Substring($i, 2), 16)
}
$bytes
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 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...
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...
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.