Mein Ver/Entschlüsseln - Eure Meinung

Für allgemeine Fragen zur Programmierung mit PureBasic.
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Hallo TroaX.
Doch, wenn auch langsam und schwerfällig, aber so langsam beginne ich wohl zu verstehen.
Beispiel:

Code: Alles auswählen

wert1 = 65532
wert2 = 256
Debug Pow(wert1, wert2)
Als Ergebniss kommt "+Infinity" heraus.
Würde das Passwort stimmen, würde mein Prg werte erzeugen, die ein sinnvolles Ergebnis liefert.

Nun kenne ich mich mit XML oder JSON so garnicht aus, habe mich noch nie damit beschäftigt.
Aber es gibt ja auch andere Fälle, wo etwas nicht stimmen kann.
Zu große / kleine Variablen o.ä.
Überprüfe ich solches verhalten in meinem Prg brauche ich vorher tatsächlich auch kein Passwort / Hashwert zu speichern.
Ok. Macht Sinn. Werde mich in diese Richtung mal weiter beschäftigen.

Und gibt jemannd ein falsches Wort ein, hat der halt Pech gehabt.
Nach einem dritten Fehlversuch bricht mein Prg ab und löscht die Dateien.
Das macht zumindest beim zurück kopieren der Dateien nochmal zusätzlich Arbeit. Grins.

Ok. Danke für Deine / Eure gedult.
Gruß: Bernd
PB 5.31 (x86) & (x64) Win10
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Hallo TroaX. Und alle Anderen.

Wahrscheinlich habe ich es falsch angefangen, und dann ist es Entgleis.
Aber vermutlich bin ich nur einfach zu blöde zum kapieren.

Die AES- Funktionen nutze ich ja bereits.

Und egal, wie und wo ich nun Vergleiche anstelle, ob alles Ok ist;
Am Anfang stehe ich immer vor folgendem Problem:
Ich gebe ein Passwort ein.
Wie erzeuge ich daraus 1nen bzw. zwei Schlüssel für die AES- Funktionen?
AESKey$ & AESIni$
Hierbei sollte mir ursprünglich meine "erzeuge_schluessel" Procedure helfen.
Nochmal Dank : Bernd

Code: Alles auswählen

Procedure.s Create_AESKey(passwort$)
  schluessel.s = ""
  j = 1
  For i = 1 To 32
    schluessel + Mid(passwort$, j, 1)
    j + 1 : If j > Len(passwort$) : j = 1 : EndIf
  Next
  ProcedureReturn schluessel
EndProcedure

Procedure.s Create_AESIni(passwort$)
  schluessel.s = ""
  j = Len(passwort$)
  For i = 1 To 16
    schluessel + Mid(passwort$, j, 1)
    j - 1 : If j < 1 : j = Len(passwort$) : EndIf
  Next
  ProcedureReturn schluessel
EndProcedure


Procedure.s EnAES(String$, Key$, ini$)
  If key$ = "" : ProcedureReturn String$ : EndIf
  
  Protected *CipheredString
 
  While Len(String$) < 16
    String$+Chr(10)
  Wend

  *CipheredString   = AllocateMemory(StringByteLength(String$))
  
  Key$ = LSet(Key$, 32, Chr(32))
  ini$ = LSet(ini$, 16, Chr(32))
  
  If AESEncoder(@String$, *CipheredString, StringByteLength(String$), @Key$, 256, @ini$);?Init)
    For n = 0 To Len(String$)-1
      Output$ + Str(PeekC(*CipheredString+n*SizeOf(Character))) + " "
    Next
  EndIf

  FreeMemory(*CipheredString)

  ProcedureReturn Output$
 
EndProcedure

Procedure.s DeAES(String$, Key$, ini$)
  If key$ = "" : ProcedureReturn String$ : EndIf
  
  Protected *Buffer = AllocateMemory(CountString(String$," ")*SizeOf(Character))
  Protected *DecipheredString = AllocateMemory(CountString(String$," ")*SizeOf(Character))
 
  For n = 0 To CountString(String$," ")-1
    PokeC(*Buffer+n*SizeOf(Character), Val(StringField(String$, n+1, " ")))
  Next
  
  Key$ = LSet(Key$, 32, Chr(32))
  ini$ = LSet(ini$, 16, Chr(32))
  
  If AESDecoder(*Buffer, *DecipheredString, MemorySize(*Buffer), @Key$, 256, @ini$);?Init)
    Output$ = RTrim(PeekS(*DecipheredString, CountString(String$," ")), Chr(10))
  EndIf

  FreeMemory(*DecipheredString)
  FreeMemory(*Buffer)

  ProcedureReturn Output$
EndProcedure

; -------------------------------------------------------------------------------------------------

passwort$ = "Passwort"
AESKey$ = Create_AESKey(passwort$)
AESIni$ = Create_AESIni(passwort$)
string$ = "abc def abcdef"
ergebnis$ = EnAES(string$, AESKey$, AESIni$)
Debug ergebnis$

passwort$ = InputRequester("", "", passwort$)
AESKey$ = Create_AESKey(passwort$)
AESIni$ = Create_AESIni(passwort$)
klartext$ = DeAES(ergebnis$, AESKey$, AESIni$)
Debug klartext$

a$ = StringField(klartext$, 1, " ")
b$ = StringField(klartext$, 2, " ")
c$ = StringField(klartext$, 3, " ")
Debug "   "
Debug a$
Debug b$
Debug c$
If a$ + b$ = c$
  Debug "Ok"
Else
  Debug "Falsch"
EndIf
PB 5.31 (x86) & (x64) Win10
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von GPI »

Ich hab mein Beispiel oben angepasst.

Wie man die zwei Keys erzeugt, zeig ich in meinen Beispiel - du kannst bspw den SH3-Fingerprint nutzen. Der wird eindeutig aus den Key erzeugt. Durch das wiederholte "Fingerprinten" wird zusätzliche Rechenzeit verbraten. Der Key darf nicht zu schnell erzeugt werden, ansonsten wird er angegriffen, weils schneller geht.

Den zweiten "Key" - also den IV ist nur ein Startwert. Den braucht man nicht geheim zu halten. Es geht nur darum, das die verschlüsselung nicht immer mit "0" beginnt, sondern immer mit einen anderen Wert. Meines Wissens nach gibt es "Angriffszenarios" wo es deutlich leichter ist zu entschlüsseln, wenn man immer mit den gleichen Startwert beginnt.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
TroaX
Beiträge: 699
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Linux Mint | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Linux Mint
Wohnort: NRW
Kontaktdaten:

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von TroaX »

Freut mich das der Groschen gefallen ^^
ch gebe ein Passwort ein.
Wie erzeuge ich daraus 1nen bzw. zwei Schlüssel für die AES- Funktionen?
AESKey$ & AESIni$
Also als erstes solltest du dich vom Gedanken verabschieden, das du beim Schlüssel und beim Vektor es mit einem String zu tun hast. Beides sind bei einer 256 Bit Verschlüsselung 32 Byte große Datenblöcke. Ein Hash mit 256 Bit erzeugt also ebenfalls einen 32 Byte großen Datenblock (64 Hexa-Dezimalstellen | 2 x Hex = 1 Byte). Du hast also zwei Möglichkeiten. entweder muss der Nutzer zwei Passwörter eingeben oder du musst einen der beiden Datenblöcke speichern.

Du kannst aber auch Den Vektor aus einem Benutzernamen erzeugen ;)

Ich würde es also folgendermaßen machen (damit es einfach bleibt):
1. Nehme meine Security-Bibliothek: https://github.com/reVerBxTc/PBExpress/ ... ecurity.pb
Binde sie ein:

Code: Alles auswählen

XincludeFile "pbesecurity.pb"
2. Generiere einen Salt z.B. mit:

Code: Alles auswählen

Salt.s = PBESecurity::GeneratePassword()
Die Funktion generiert einen String zwischen 8 und 24 Zeichen und hat eine größere Wahrscheinlichkeit, das Sonderzeichen mit dabei sind.
3. Dann würfelst du eine Zahl zwischen 100.000 und 400.000 (wir müssen nicht übertreiben ;) ) zufällig aus, addierst sie mit 100.000, damit wir mindestens sichere 200.000 Cycles haben.
4. Speichere den Salt sowie die Anzahl der Cycles ab. Denn beide sollen Attacken auf das Passwort ineffizient machen und beeinflussen selbst wenn sie bekannt sind die Sicherheit nicht.
5. Mach aus dem Passwort, dem Salt und den Cycles der Schlüssel für die Verschlüsselung:

Code: Alles auswählen

KeyHash.s = PBESecurity::PBKDF2(#PB_Cipher_SHA3,256,PasswortString,Salt,Cycles)
; Parameter 1: Der Hash-Algorithmus (SHA3 empfohlen - Die UseSHA3Fingerprint Prozedur macht die Lib schon selbst)
; Parameter 2: Die Tiefe des Hashes (256 Bit = 64 Hex-Stellen = 32 Byte)
; Parameter 3: Das Passwort, das der Nutzer eingegeben hat
; Parameter 4: Der Salt, den du vorher erzeugt hast bzw. aus der Datei geholt hast
; Parameter 5: Die Anzahl der Wiederholungen, die PBKDF2 verschlüsselt (je mehr, um so länger und umso sicherer = 1 Sekunde sind knapp 300.000 Cycles auf einem i5 4470)
Um jetzt noch den Vektor zu bekommen:
1. Erzeuge mit CryptRandomData mindestens 10 Datenblöcke mit 32 Byte. Diese Blöcke brauchste weder mit XOR oder Hash oder sonstwas behandeln. 32 Byte kryptografisch sichere Zufallsdaten bleiben auch kryptografisch sichere Zufallsdaten, wenn du sie mit anderen Daten verwurstet. Es wird dadurch nicht sicherer ;)
2. Speichere diese Datenblöcke in einer Datei
3. Wähle beim Verschlüsseln einen der Datenblöcke zufällig aus und verwende ihn als Initialisierungsvektor der AES Verschlüsselung.
4. Beim Entschlüsseln erzeugst du zuerst den Passwortschlüssel wie oben beschrieben und mit diesem probierst du alle 10 Vektoren durch, bis ein valides Ergebnis kommt. Passiert dies nicht, war das eingegebene Passwort falsch. Denn da wir ja nur mit den 10 Vektoren arbeiten, ist einer der 10 auf jeden Fall richtig. Also kann nur der Schlüssel (also das Passwort) falsch sein.

Alternative zur Vektoren Liste:
Frage neben dem Passwort auch einen Benutzernamen ab und verfahre mit diesem genauso wie mit dem Passwort. Aber ein einfacher 256 Bit Hash ohne Zyklen etc. tut es auch. Es ist im Vergleich zu 10 bereits festen Vektoren eh schon deutlich sicherer. Allerdings für den Nutzer unangenehm, weil er beides eingeben muss. Und wenn du den Benutzernamen für spätere Nutzungen merken willst, dann kannste das Feld auch gleich ganz weglassen und stattdessen die Vektoren-Liste nehmen ;)

Noch ein paar kleine Tipps:
1. Du kannst den Salt, die Cycles sowie die Vektoren easy in einer Textdatei speichern und diese Zeilenweise einlesen. Du kannst in die erste Zeile den Salt schreiben, in die zweite die Anzahl an Zyklen und Zeile 3 bis 12 sind dann die Vektoren. Du kannst die Vektoren als Hex-Code ausgeben. Dann hat jeder Vektor ebenfalls 64 Hex-Stellen. Du kannst aber auch alles im Byteformat speichern. Du musst dann nur daran denken, alles mit fester Größe zuerst zu speichern. Die Vektoren haben alle jeweils 32 Byte. Die nimmst du zuerst. Die Zyklen speicherst du z.B. in einem Long. Der hat immer 4 Byte und der Rest der Datei gehört zum Salt und da dieser variabel ist, hat er auch immer eine unterschiedliche Bytegröße. Die Größe des Salt's ist dann immer:

Code: Alles auswählen

BYTEGRÖßE_DATEI - (10 * 32 + 4)
2. Du kannst auch die Validität der Daten mit Hashes prüfen. Du erzeugst einfach 2 128 Bit Hashes, speicherst diese zusammen mit Salt, Zyklen und Vektor in der Datei ab, fügst einen am Anfang und einen am Ende der Daten ein. Dann kannst du beim Entschlüsseln die ersten und die letzten 16 Byte mit den Hashes vergleichen. Ich nehme bei sowas immer lieber 2 Hashes, um die Kollisionswahrscheinlichkeit bei Fehlentschlüsselungen zu minimieren. Versuche aber nach Möglichkeit nie einen Hash zu nehmen, der aus dem Datenbestand generiert wurde. Denn auf Grund des Datenumfanges ist die Kollisionswahrscheinlichkeit relativ hoch. Auch hier könnten Fehlentschlüsselungen zu Fehlern führen.

PS: Da war wieder jemand schneller xD
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Linux Mint
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: N150 Mini-PC | 16 GB RAM | Debian 13+CasaOS
Coding: Purebasic, Spiderbasic, GDevelop, PHP
Blog: https://techtroax.de
Repos: https://codeberg.org/TroaX
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Hallo Ihr Beiden, TroaX, GPI.
Nochmals vielen Dank für Eure Unterstützung.
Ich habe mir Eure Beispiele heruntergeladen und werde nun viel damit herum experimentieren.

Ich habe bereits viel daraus gelernt, was mir nun auch bei der Suche nach Fachbegriffen weiterhilft.

Dank & Gruß: Bernd

Noch ein PS an die Forumadmins.
Bei der Eingabe dieses Textes hat sie die Fehlerüberprüfung aufgehängt.
Nun wird alles, was ich schreibe als falsch geschrieben markiert.
Weiteres PS: Nach Klick auf die Vorschau ist nun wieder alles in Ordnung.
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von NicTheQuick »

BSP hat geschrieben:Noch ein PS an die Forumadmins.
Bei der Eingabe dieses Textes hat sie die Fehlerüberprüfung aufgehängt.
Nun wird alles, was ich schreibe als falsch geschrieben markiert.
Weiteres PS: Nach Klick auf die Vorschau ist nun wieder alles in Ordnung.
Welche Fehlerüberprüfung meinst du? Hier gibt es keine. Oder meinst du die Rechtschreibprüfung? Die hängt mit deinem Browser zusammen.
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Hallo Nick.
Oder meinst du die Rechtschreibprüfung?
Ja, die meinte ich.
Die hängt mit deinem Browser zusammen.
Ok. Also mein Fehler. Sorry
Gruß: Bernd
PB 5.31 (x86) & (x64) Win10
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Hallo Allerseits.
Ich möchte Euch nochmals meine letzte Arbeit vorstellen
und bitte um Eure Kritik.

Zunächst:
Es hat mich gestört, das der AESIni gespeichert werden soll.
Nun ermittel ich auch den per Zufall aus der Quersumme des Passwort.
Weiter hat es mich gestört, im Kontrollstring das Salt mit zu verschlüsseln.
Das mache ich nicht, weil im Kontrollstring nichts bekanntes stecken soll.
Den Salt muß ich speichern. Das hat mich gestört.
Darum wird nun auch der Salt mit der Quersumme verbunden.

Und dann noch eine weiter Frage:
Ich lese immer wieder, ein Fingerprint sei einmalig
und es sei nicht möglich, den Fingerprint zurück zu entwickeln.
Nun lese ich aber, das einige den Fingerprint sogar über 100tausend mal mit sich selber erzeugen.
Ist der Fingerprint also doch nicht so sicher?

So: Hier nun mein Prg.
Danke & Gruß: Bernd

Code: Alles auswählen

UseSHA3Fingerprint()


Procedure.s HexToStr(hex$, w = 2)
  ; w gibt die Länge/Weite des Hex an. Bsp: $FF , $FFFF , $FFFFFF
  Protected str$, i
  For i = 0 To Len(hex$) / w - 1
    str$ + Chr(Val("$" + Mid(hex$, 1+i*w, w)))
  Next
  ProcedureReturn str$
EndProcedure

Procedure.s StrToHex(str$, w = 2)
  ; w gibt die Länge/Weite des Hex an. Bsp: $FF , $FFFF , $FFFFFF
  Protected hex$, i
  For i = 1 To Len(str$)
    hex$ + RSet(Hex(Asc(Mid(str$, i, 1))), w, "0")
  Next
  ProcedureReturn hex$
EndProcedure

Procedure.s Create_RndStr(w, bis, von)
  For i = 1 To w
    s$ + Chr(Random(bis, von))
  Next
  ProcedureReturn s$
EndProcedure

;-

Procedure.s EnAES(String$, Key$, ini$)
  If key$ = "" : ProcedureReturn String$ : EndIf
  
  Protected *CipheredString
 
  While Len(String$) < 16
    String$+Chr(10)
  Wend

  *CipheredString   = AllocateMemory(StringByteLength(String$))
  
  Key$ = HexToStr(Key$);LSet(Key$, 32, Chr(32))
  ini$ = HexToStr(ini$);LSet(ini$, 16, Chr(32))
  
  If AESEncoder(@String$, *CipheredString, StringByteLength(String$), @Key$, 256, @ini$);?Init)
    For n = 0 To Len(String$)-1
      Output$ + Str(PeekC(*CipheredString+n*SizeOf(Character))) + " "
    Next
  EndIf

  FreeMemory(*CipheredString)

  ProcedureReturn Output$
 
EndProcedure

Procedure.s DeAES(String$, Key$, ini$)
  If key$ = "" : ProcedureReturn String$ : EndIf
  
  Protected *Buffer = AllocateMemory(CountString(String$," ")*SizeOf(Character))
  Protected *DecipheredString = AllocateMemory(CountString(String$," ")*SizeOf(Character))
 
  For n = 0 To CountString(String$," ")-1
    PokeC(*Buffer+n*SizeOf(Character), Val(StringField(String$, n+1, " ")))
  Next
  
  Key$ = HexToStr(Key$);LSet(Key$, 32, Chr(32))
  ini$ = HexToStr(ini$);LSet(ini$, 16, Chr(32))
  
  If AESDecoder(*Buffer, *DecipheredString, MemorySize(*Buffer), @Key$, 256, @ini$);?Init)
    Output$ = RTrim(PeekS(*DecipheredString, CountString(String$," ")), Chr(10))
  EndIf

  FreeMemory(*DecipheredString)
  FreeMemory(*Buffer)

  ProcedureReturn Output$
EndProcedure

;-


Procedure.s Passwort_Eingeben()
  pw$ = "Passwort"
  ProcedureReturn pw$
EndProcedure


Procedure  Schluessel_pruefen(passwort$, kontrollstr$, salz$, lauf)
  w = 5
  ; Quersumme ermitteln. Nachkommastellen werden frech ignoriert.
  qs = 0 : For i = 1 To Len(passwort$) : qs + Asc(Mid(passwort$, i, 1)) : Next
  qs = qs / Len(passwort$)
  
  AESKey$ = Left(salz$, qs) + passwort$ + Mid(salz$, qs)
  AESIni$ = ""
  
  For i = 1 To lauf * (qs * w)
    AESKey$ = StringFingerprint(AESKey$, #PB_Cipher_SHA3, 256)
    If i = qs * w : AESIni$ = AESKey$ + salz$ : EndIf
    If AESIni$ <> ""
      AESIni$ = StringFingerprint(AESIni$, #PB_Cipher_SHA3, 256)
    EndIf
  Next
  klartext$ = DeAES(kontrollstr$, AESKey$, AESIni$)
  a$ = StringField(klartext$, 1, "|")
  b$ = StringField(klartext$, 2, "|")
  If StringFingerprint(a$, #PB_Cipher_SHA3, 512) = b$
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure.s Erzeuge_Schluessel(passwort$, salz$)
  Protected schluessel$
  w = 5 ; Wem das zu kurz ist, kann das ja vergrössern. 
        ; Aber die Procedure  Schluessel_pruefen nicht vergessen !
  lauf = Random(200, 100)
  ; Quersumme ermitteln. Nachkommastellen werden frech ignoriert.
  qs = 0 : For i = 1 To Len(passwort$) : qs + Asc(Mid(passwort$, i, 1)) : Next
  qs = qs / Len(passwort$)
  
  AESKey$ = Left(salz$, qs) + passwort$ + Mid(salz$, qs)
  AESIni$ = ""
  
  For i = 1 To lauf * (qs * w)
    AESKey$ = StringFingerprint(AESKey$, #PB_Cipher_SHA3, 256)
    If i = qs * w : AESIni$ = AESKey$ + salz$ : EndIf
    If AESIni$ <> ""
      AESIni$ = StringFingerprint(AESIni$, #PB_Cipher_SHA3, 256)
    EndIf
  Next
  
  a$ = StrToHex(Create_RndStr(128, 255, 1), 2)
  kontrollstring$ = a$ + "|" + StringFingerprint(a$, #PB_Cipher_SHA3, 512)
  kontrollstring$ = EnAES(kontrollstring$, AESKey$, AESIni$)
  schluessel$ = Str(lauf) + ":" + AESKey$ + ":" + AESIni$ + ":" + kontrollstring$
  
  ProcedureReturn schluessel$
EndProcedure


; -------------------------------------------------------------------------------------------------

salz$ = Create_RndStr(256, 255, 1) ; 1, damit NullStrings ausgeschossen sind
passwort$ = Passwort_Eingeben()

schluessel$ = Erzeuge_Schluessel(passwort$, salz$)
Debug schluessel$
lauf     = Val(StringField(schluessel$, 1, ":"))
AESKey$      = StringField(schluessel$, 2, ":")
AESIni$      = StringField(schluessel$, 3, ":")
kontrollstr$ = StringField(schluessel$, 4, ":")
Debug "  w = " + lauf
Debug "Key = " + AESKey$
Debug "Ini = " + AESIni$
Debug "Kon = " + kontrollstr$
; --- Nun "lauf, Salz" & "Kontrollstr" speichern
salz$ = StrToHex(salz$)
; speichern()

; ---

; --- Bei Start des Prgs.
; laden()
salz$ = HexToStr(salz$)
passwort$ = InputRequester("", "", passwort$)
If Schluessel_pruefen(passwort$, kontrollstr$, salz$, lauf)
  Debug "Ok"
Else
  Debug "Falsch"
EndIf
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
TroaX
Beiträge: 699
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Linux Mint | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Linux Mint
Wohnort: NRW
Kontaktdaten:

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von TroaX »

Mach dir keine Sorgen. Deine Empfindungen sind nur etwas überempfindlich.

Den Salt kannst du speichern. Den aus dem Passwort heraus zu errechnen, macht keinen Sinn, da dieser dann kein Salt ist. Du errechnest einfach einen neuen String aus einem bestehenden, der am Ende nur mit dem Ausgangspasswort wieder vereint wird. Du vergisst aber, das du das Passwort selbst gegen Rainbow-Tables, Dictonaries und Bruteforce absichern musst. Nicht den Schlüssel. Von daher ist das Speichern eines Salt's vollkommen legitim und führt, so lange du Derivation-Routinen verwendest zu der Sicherheit, die du benötigst. Damit eine Derivation funktioniert, musst du natürlich auch den Kostenfaktor (Cycles) speichern, da du sonst immer andere Ergebnisse erhälst. Wenn du keinen Initialisierungs-Vektor speichern willst, frage einfach zu dem Passwort zusätzlich einen Benutzernamen ab und verwende dessen 256-Bit Hash als Vektor. Ansonsten wirst du ums speichern nicht herum kommen. Aber wie ich schon geschrieben habe, kannst du das zur Not als eine Art Pepper machen und mit X verschiedenen Vektoren einfach durchprobieren bis einer passt.

Sicherheit ist von 3 Faktoren Abhängig:
1. Algorithmen zur Verschlüsselung oder zum Hashen benötigen wenig Potential zur Brechung oder zur Kollision. Bei Hashes kannst du im Internet nachlesen, ob gebrochen oder nicht und wie stark der Effekt ist. Und auch Verschlüsselungen sind Dokumentiert. Um es kurz zu machen: Zuverlässigkeit der Algorithmen.
2. Sicherheit der Informationen in den Algorithmus. Dazu ist zum Beispiel ein Salt da, der die Sicherheit des Eingabesttrings erhöht. Dieser schützt ohne Derivation bereits einigermaßen gegen Bruteforce und Dictonaries. Kann aber bei Kundigen dazu führen, das er sich für seine Dictonary-Routinen den gespeicherten Salt berücksichtigt. Aber dagegen hilft die Key-Derivation. Es bringt einem nichts, ein Wörterbuch mit Milliarden von Einträgen durchlaufen zu lassen, wenn jeder Versuch lange dauert. Das macht das ganze völlig ineffizient.
3. Rechenzeit!!!! <- Das ist der wichtigste Faktor. Du kannst Schlüssel und Vektor so viel absichern wie du willst. Am Ende funktionieren Bruteforce-Angriffe eh nur auf den Algorithmus AES256 und nicht auf deine Implementierung. Das kannst du auf Biegen und Brechen nicht verhindern. Was du auch nicht verhindern kannst ist, das ein Angreifer dein Programm deassembliert und sich den Assemblercode ansieht. Und da wird er sehen, was du da veranstaltest und wenn du Pech hast, findet er einen Weg, deinen Algorithmus zu brechen! Und genau deswegen sollte man nach Möglichkeit etablierte und verbreitete Methoden einsetzen und nicht selbst etwas versuchen, zu verwursten. Deswegen Strecke liber mit einer Key-Derivation die Rechenzeit, um dein Passwort abzusichern und versuche nicht, AES abzusichern. Du hast nur eine Schnittstelle und die ist immer gleich.

Um es auf den punkt zu bringen: Wenn du alles versuchst, aus dem Passwort zu errechnen, verringerst du nur die Auflösung an möglichen Eingabedaten und spielst den Angreifern in die Hände.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Linux Mint
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: N150 Mini-PC | 16 GB RAM | Debian 13+CasaOS
Coding: Purebasic, Spiderbasic, GDevelop, PHP
Blog: https://techtroax.de
Repos: https://codeberg.org/TroaX
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Mein Ver/Entschlüsseln - Eure Meinung

Beitrag von BSP »

Guten morgen TroaX.
Ich habe nochmal nach den Begriffen gegoogelt, die Du so genannt hast.
(Hoffentlich habe ich das so halbwegs richtig verstanden).
Durch das anfügen eines Salt (ans Passwort) müssen ja weitere "Rainbow- Table" angelegt werden,
je länger der Salt, umso mehr Tabellen.
Siehe:
https://de.wikipedia.org/wiki/Rainbow_Table
Nun wurde dort auch vom "Pfeffern" gesprochen.
Wird also durch das zerlegen des Salt durch die Quersumme meines Passwortes nicht ein "Pfeffer" statt "Salt"?
Wenn auch nur ein schwacher Pfeffer, denn ganz unbekannt wird der Salt ja nicht, nur vervielfacht.
(Pi mal Auge ums 64 fache, je nach Umfang der erlaubten Zeichen ? (Aa..., 123...usw.))
Oder stellt bereits das bilden der Quersumme eine Gefahr dar?
Beispiel 2 Zeichen: (4 + 4) / 2 = (1 + 7) / 2 = (3 + 5) / 2 usw.

Soweit fürs erste.
Weitere fragen werden sicher noch folgen.
Gruß & Dank: Bernd

PS. Ich grüble schon die ganze Zeit über einen weiteren Punkt nach. Aber meine Gedanken verknoten sich langsam.
An einer Stelle in meinem Verschlüsselungslauf greife ich ja einen Wert ab,
den ich dann mit dem Salt verbinde und so zum bilden des AESIni verwende.
Stellt nicht gerade dieses abgreifen eine Tür dar?
PB 5.31 (x86) & (x64) Win10
Antworten