Seite 1 von 1

String ver- und entschlüsseln

Verfasst: 20.09.2021 19:01
von stevie1401
Ich suche verzweifelt nach einer Möglichkeit einen String zu verschlüsseln, aber auch nach einer Möglichkeit diesen wieder entschlüsseln zu können.
Bestimmt gibt es sowas hier im Forum schon, aber ich bin echt zu dusselig das zu finden.
Kann mir jemand helfen?

Re: String ver- und entschlüsseln

Verfasst: 20.09.2021 19:44
von Mijikai
Hier ein Beispiel ver- und entschlüsselt (nutzt XOR, nur für Unicode):

Code: Alles auswählen

Procedure.s StringXOR(Text.s,Key.s)
  Protected *chr.Unicode
  Protected *key.Unicode
  If Text And Key
    *chr = @Text
    *key = @Key
    Repeat
      *chr\u ! *key\u
      *key + 2
      If *key\u = #Null
        *key = @Key
      EndIf
      *chr + 2
    Until *chr\u = #Null  
    ProcedureReturn Text
  EndIf
  ProcedureReturn #Null$
EndProcedure

Re: String ver- und entschlüsseln

Verfasst: 20.09.2021 21:17
von STARGÅTE
@Mijikai: Ähm, scheint irgendwie nicht zu funktionieren, da kommt nur Müll raus:

Code: Alles auswählen

Debug StringXOR(StringXOR("Hallo Welt!", "123"), "123")
@stevie1401: Wie möchtest du denn Verschlüsseln? Soll die Länge des verschlüsselten Strings gleich der Länge des Original sein?
Soll der verschlüsselte String lesbar/darstellbar sein? Soll es kryptografisch sicher sein?
Gibt ja viele Möglichkeiten der Verschlüsselung.

Re: String ver- und entschlüsseln

Verfasst: 20.09.2021 22:30
von Mijikai
Hab den Code gefixt.

Re: String ver- und entschlüsseln

Verfasst: 20.09.2021 22:35
von NicTheQuick
So geht das leider nicht. Sobald im Passwort ein Buchstabe mit dem Originaltext übereinstimmt, entsteht ein Nullbyte und man hat den Salat:

Code: Alles auswählen

Debug StringXOR(StringXOR("Hallo Welt!", "1a3"), "1a3")
Außerdem ist das natürlich nicht verschlüsselt im modernen Sinne. Dafür macht man erst mal einen Hash vom Passwort und nutzt dann AES oder vergleichbar gutes.

Re: String ver- und entschlüsseln

Verfasst: 21.09.2021 06:08
von stevie1401
Es geht nur darum Strings verschlüsselt auf die Festplatte speichern zu können, sodass nicht jeder gleicht den Text lesen kann.
Aber natürlich muss ich auch in der Lage sein, den Text dann wieder laden und entschlüsseln zu können.

Re: String ver- und entschlüsseln

Verfasst: 21.09.2021 07:55
von stevie1401
Ich denke, ich habe es selber hingekommen:

Code: Alles auswählen



UseSHA3Fingerprint()


Declare.s Verschluesseln(Text.s, Passwort.s)
Declare.s Entschluesseln(Text.s, Passwort.s)


Global.s Text
Global.s Passwort
Global.s s

Text = "Dies ist der Text üöäß^123§ℓ«»„“"
Passwort = "Passwort"

s = Verschluesseln(Text, Passwort)
Debug "Verschlüsselt: " + s
s = Entschluesseln(s, Passwort)
Debug "Entschlüsselt: " + s
Debug "Originaltext:  " + Text
If s <> Text
  Debug "Abweichung!"
EndIf


Procedure.s Verschluesseln(Text.s, Passwort.s)
  
  ; Der Text muss mindestens 16 Zeichen lang sein
  While Len(Text) < 16
    Text + " "
  Wend
  
  Protected n, i
  Protected *Input
  Protected *Output
  Protected *AESKey
  Protected *AESInitializationVector
    
  ; Der Schlüssel für AES wird aus dem Passwort generiert, per SHA3 
  Passwort = StringFingerprint(Passwort, #PB_Cipher_SHA3, 256)
  
  ; Passwort besteht aus 64 Hexadezimalzeichen (256 Bit).
  ; Die ersten 32 Zeichen werden der AESkey, die zweiten 32 Zeichen der AESInitializationVector.
  *AESkey = AllocateMemory(64)
  *AESInitializationVector = AllocateMemory(64)
  PokeS(*AESKey, Passwort, 32, #PB_String_NoZero)
  PokeS(*AESInitializationVector, Mid(Passwort, 32), 32, #PB_String_NoZero)
  
  *Input = UTF8(Text)
  n = MemorySize(*Input)
  
  *Output = AllocateMemory(n+16) ; Die Größe muss mindestens ein Vielfaches von 16 sein
     
  AESEncoder(*Input, *Output, n, *AESKey, 256, *AESInitializationVector)
  
  Text = Base64Encoder(*output, n)
  
  FreeMemory(*Input)
  FreeMemory(*Output)
  FreeMemory(*AESKey)
  FreeMemory(*AESInitializationVector)
  
  ProcedureReturn Text
EndProcedure
    
    
Procedure.s Entschluesseln(Text.s, Passwort.s)
  
  Protected n, i
  Protected *Input
  Protected *Output
  Protected *AESKey
  Protected *AESInitializationVector
    
  ; Der Schlüssel für AES wird aus dem Passwort generiert, per SHA3 
  Passwort = StringFingerprint(Passwort, #PB_Cipher_SHA3, 256)
  
  ; Passwort besteht aus 64 Hexadezimalzeichen (256 Bit).
  ; Die ersten 32 Zeichen werden der AESkey, die zweiten 32 Zeichen der AESInitializationVector.
  *AESkey = AllocateMemory(64)
  *AESInitializationVector = AllocateMemory(64)
  PokeS(*AESKey, Passwort, 32, #PB_String_NoZero)
  PokeS(*AESInitializationVector, Mid(Passwort, 32), 32, #PB_String_NoZero)
  
  n = Len(Text) * 3 / 4
  If Right(Text, 1) = "="
    n - 1
  EndIf
  If Right(text, 2) = "=="
    n - 1
  EndIf
  *Input = AllocateMemory(n)
  Base64Decoder(Text, *Input, n)
  
  *Output = AllocateMemory(n)
     
  If AESDecoder(*Input, *Output, n, *AESKey, 256, *AESInitializationVector) = 0
    Debug "Fehler beim Decodieren"
    ProcedureReturn
  EndIf
  Text = PeekS(*Output, -1, #PB_UTF8)

  FreeMemory(*Input)
  FreeMemory(*Output)
  FreeMemory(*AESKey)
  FreeMemory(*AESInitializationVector)
  
  ProcedureReturn text
EndProcedure


Re: String ver- und entschlüsseln

Verfasst: 21.09.2021 12:30
von NicTheQuick
Normalerweise leitet man den Initialisierungsvektor nicht von dem Passwort ab, sondern erzeugt kryptografisch sicher einen Zufallswert, den man dem verschlüsselten Ergebnis voranstellt. Deine Variante geht natürlich trotzdem und sollte sicher genug sein, es ist trotzdem anders gedacht.
Viel schlimmer ist das hier: Der StringFingerprint() sollte nicht einfach so als Hex-String benutzt werden, sondern zunächst in einen Binärwert umgewandelt und dann benutzt werden. PB-Strings sind nämlich Unicode, d.h. jedes zweite Byte ist 0. Und da es zusätzlich noch ein Hexstring ist, verschwendest du sogar 12 Bit aus insgesamt 16 Bit pro Zeichen, die immer 0 sind. Deine Entropie ist also nicht mehr so hoch wie sie sein sollte.

Re: String ver- und entschlüsseln

Verfasst: 22.09.2021 19:46
von stevie1401
Aha!
So besser?

Code: Alles auswählen




UseSHA3Fingerprint()


Declare.s Verschluesseln(Text.s, Passwort.s)
Declare.s Entschluesseln(Text.s, Passwort.s)


Global.s Passwort
Passwort = "Passwort"


NewList Text.s()

AddElement(Text())
Text() = "Kurz"
AddElement(Text())
Text() = "Mittellanger Text, der getestet wird."
AddElement(Text())
Text() = "Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890. Dies ist ein ganz ganz ganz langer Text 1234567890."
AddElement(Text())
Text() = "Dies ist der Text mit Sonderzeichen üöäß^123§ℓ«»„“"

Global.s s
ForEach Text()
  s = Verschluesseln(Text(), Passwort)
  Debug "Verschlüsselt: " + s
  s = Entschluesseln(s, Passwort)
  Debug "Entschlüsselt: |" + s + "|"
  Debug "Originaltext:  |" + Text() + "|"
  If s <> Text()
    Debug "Abweichung!"
  EndIf
Next Text()


Procedure.s Verschluesseln(Text.s, Passwort.s)
  
  ; Der Text muss mindestens 16 Zeichen lang sein, gegebenenfalls wird er mit Leerzeichen aufgefüllt.
  If Len(Text) < 16
    Text = LSet(Text, 16)
  EndIf
  
  Protected n, i
  Protected *Input
  Protected *Output
  Protected *AESKey
  Protected *AESInitializationVector
    
  ; Der Schlüssel für AES (*AESKey) wird aus dem Passwort generiert, per SHA3 (256 Bit)
  Passwort = StringFingerprint(Passwort, #PB_Cipher_SHA3, 256)
  *AESkey = AllocateMemory(32)
  For i = 0 To 31
    PokeB(*AESKey + i, Val("$" + Mid(passwort, 2 * i, 2)))
  Next i
  
  ; Der Initialisierungsvektor wird zufällig belegt und später dem verschlüsselten Text vorgestellt
  *AESInitializationVector = AllocateMemory(32)
  RandomData(*AESInitializationVector, 32)
  
  *Input = UTF8(Text)
  n = MemorySize(*Input)
  
  *Output = AllocateMemory(n+16) ; Die Größe muss mindestens ein Vielfaches von 16 sein
     
  AESEncoder(*Input, *Output, n, *AESKey, 256, *AESInitializationVector)
  
  Text = Base64Encoder(*AESInitializationVector, 32) + ":" + Base64Encoder(*output, n)
  
  FreeMemory(*Input)
  FreeMemory(*Output)
  FreeMemory(*AESKey)
  FreeMemory(*AESInitializationVector)
  
  ProcedureReturn Text
EndProcedure
    
    
Procedure.s Entschluesseln(Text.s, Passwort.s)
  
  Protected n, i
  Protected *Input
  Protected *Output
  Protected *AESKey
  Protected *AESInitializationVector
    
  ; Der Schlüssel für AES wird aus dem Passwort generiert, per SHA3 
  Passwort = StringFingerprint(Passwort, #PB_Cipher_SHA3, 256)
  *AESkey = AllocateMemory(32)
  For i = 0 To 31
    PokeB(*AESKey + i, Val("$" + Mid(passwort, 2 * i, 2)))
  Next i
  
  ; Der Initialisierungsvector steht am Anfang vom Text im Hexadezimalform
  *AESInitializationVector = AllocateMemory(32)
  Base64Decoder(Text, *AESInitializationVector, 32)
  
  ; Den vorderen Teil mit dem Initialisierungsvektor abschneiden
  Text = Mid(Text, 32 * 4 / 3 + 4)
  ; Die Länge des resultierenden Textes ermitteln
  n = Len(Text) * 3 / 4
  If Right(Text, 1) = "="
    n - 1
  EndIf
  If Right(text, 2) = "=="
    n - 1
  EndIf
  
  *Input = AllocateMemory(n)
  Base64Decoder(Text, *Input, n)
  
  *Output = AllocateMemory(n)   
  If AESDecoder(*Input, *Output, n, *AESKey, 256, *AESInitializationVector) = 0
    Debug "Fehler beim Decodieren"
    ProcedureReturn
  EndIf
  Text = PeekS(*Output, -1, #PB_UTF8)

  FreeMemory(*Input)
  FreeMemory(*Output)
  FreeMemory(*AESKey)
  FreeMemory(*AESInitializationVector)
  
  ProcedureReturn Text
EndProcedure