Kontakt
DSVGO
Historie | |
---|---|
27.08.2007 | Behandeln eines StrConv-Bugs, welcher bei leeren Zeichenketten auftritt. Vielen Dank an Manuel Ratzinger für den entsprechenden Fehler-Hinweis! |
06.06.2005 | Debugging; Umstellung auf (etwas langsameres aber robustes) Verfahren via StrConv-Funktion |
22.09.2001 | Erste Version benutzt Speichermapping |
Für viele Anwendungsbereiche wird eine schnelle Verschlüsselung benötigt: Ob zur Speicherung von Passwörtern in Datenbanken, oder zur Unkenntlichmachung von Texten oder beliebigen Dateien.
Die unten vorgestellten Routinen erfüllen zumindest folgende Anforderungen:
Nachfolgend wird u.a. gezeigt, wie ein Byte-Array verschlüsselt werden kann, und wie dies dazu genutzt werden kann, einen String schnell zu verschlüsseln.
Einen Text mit Passwort "abc" verschlüsseln und anschließend wieder entschlüsseln:
Dim s As String s = "Hallo Welt!" EncodeString s, "abc" 'das (unleserliche) Ergebnis steht in s EncodeString s, "abc" 'jetzt steht wieder "Hallo Welt!" in s
Via Funktion verschlüsselten Text hexadezimal anzeigen:
MsgBox HexDump(EncodeStr("Hallo", "abc")) 'zeigt "B69D3F3F3F" an
Ein Byte-Array verschlüsseln (am fiktiven Beispiel einer Binärdatei):
Dim b() As Byte 'ReadData "c:\test\bla.exe", b EncodeArrayB b, "abc" 'WriteData "c:\test\bla.exe", b
Das Herzstück der Verschlüsselung (der eigentliche Algorithmus) ist hier zu finden: Ein gegebenes Byte-Array wird Byte für Byte durch Anwendung der Xor-Funktion verschlüsselt. Da die zweimalige Anwendung von Xor (mit dem gleichen Wert) den ursprünglichen Wert wiederherstellt, ist die Entschlüsselung mit dieser Routine ebenfalls möglich.
Public Sub EncodeArrayB( _ ByRef ByteArray() As Byte, _ Optional ByRef Password As String _ ) Const MagicByte As Byte = &HFF Dim PwdLen As Long Dim PwdAsc As Byte Dim i As Long Dim j As Long Dim LB As Long Dim UB As Long PwdLen = Len(Password) Select Case PwdLen Case 0 'Kein Password verwenden: For i = LBound(ByteArray) To UBound(ByteArray) ByteArray(i) = ByteArray(i) Xor MagicByte Xor (i And &HFF) Next i Case 1 'Einzelnes Zeichen als Password verwenden: PwdAsc = Asc(Password) Xor MagicByte For i = LBound(ByteArray) To UBound(ByteArray) ByteArray(i) = ByteArray(i) Xor PwdAsc Xor (i And &HFF) Next i Case Else 'Password verwenden: LB = LBound(ByteArray) UB = UBound(ByteArray) 'Buchstaben-weise das Passwort durchlaufen: For j = 1 To PwdLen PwdAsc = Asc(Mid$(Password, j, 1)) Xor MagicByte For i = LB To UB Step PwdLen ByteArray(i) = ByteArray(i) Xor PwdAsc Xor (i And &HFF) Next i LB = LB + 1 Next j End Select End Sub
Man beachte, wie durch die Fallunterscheidung nach der Passwort-Länge eine optimale Performance sichergestellt wird.
Um Byte-weise auf die einzelnen Zeichen eines Strings zuzugreifen, wird der String an ein Byte-Array zugewiesen. VB würde eigentlich ein Zeichen in jeweils zwei Elemente des Byte-Arrays ablegen (wegen Unicode-Darstellung), daher muss der String vorher mit der VB-Funktion StrConv konvertiert werden (und hinterher wieder zurück).
Eine andere Idee wäre der Zeichen-weise Zugriff via Mid$ gewesen, sowohl beim Lesen, als auch beim Schreiben. Aber im Vergleich zur direkten Operation auf Bytes (also Zahlenwerte) ist die Kodierung von Zeichen deutlich aufwändiger und langsamer; man müßte ständig die VB-Funktionen Asc und Chr$ benutzen, welche nun wirklich nicht die schnellsten sind.
Also habe ich mich für die erste Idee entschieden:
Public Sub EncodeString( _ ByRef Text As String, _ Optional ByRef Password As String _ ) Dim Bytes() As Byte If Len(Text) Then Bytes = StrConv(Text, vbFromUnicode) EncodeArrayB Bytes, Password Text = StrConv(Bytes, vbUnicode) End If End Sub
Die Fallunterscheidung (prüfen, ob der Text nicht leer ist) ist notwendig, da die StrConv-Funktion Probleme beim Umgang mit leeren Zeichenketten hat.
Für einzelne Fälle kann es ganz praktisch sein, den Text in der original-Variable nicht zu verändern. Daher gibt die folgende Funktion eine Kopie zurück:
Public Function EncodeStr( _ ByRef Text As String, _ Optional ByRef Password As String _ ) As String EncodeStr = Text EncodeString EncodeStr, Password End Function
© Jost Schwider, 22.09.2001-27.08.2007 - http://vb-tec.de/strcode.htm