1. Ist es vom Verfahren her sicher?
Falls mit dem in der Datei gespeichertem Key der Hash Wert von SHA1(Salt || Passwort) gemeint ist dann ja. Denoch würde ich empfehlen diesen Key nicht vollständig zu speichern. Er dient ja nur zur Erkennung ob man das richtige Passwort eingegeben hat und als sicherer Zufallswert.
2. Sollte man hierfür ein Byte- oder BlockChiper verwenden?
Ein Byte Cipher ist ein BlockCipher mit Blockgröße 8 bit
Du meintest einen StreamCipher kontrahär zum BlockCipher. Nun, das hängt vom Cipher Algorithmus selber ab, und von den Kompatibilitätsanforderungen. Zb. für Windows-Programme die mit PocketPC/Palm Programmen per
TCP/
IP kommunizieren nutze ich gerne RC4 als StreamCipher. Denoch werden BlockCipher als sicherer eingestuft. Blowfish ist ein BlockCipher.
3. Sollte man beim BlockChiper Source auf 8 Byte abrunden (falls Daten < 8 Byte)?
Dies ist nicht zwingend notwendig. Beachte das der Ciphermode nicht ECB ist, sondern zB. CBC,CTS,CTR,CFB oder ähnliche Feedback Modis. Dies ist enorm wichtig. Alle diese Modis können per "Cipher Text Stealing" jede beliebige Messagelänge 1 zu 1 verschlüsseln. Ein zusätzliches Padding ist also nicht nötig.
4. Ist mir sonst irgentwas entgangen?
Keine Ahnung, das müsstest du besser wissen als ich
Spaß beiseite, so wie es jetzt ist ist es schon besser als viele andere Lösungen.
Ich versuche hier nochmal zusammenzufassen.
Code:
Key = Benutzerpasswort
Salt = Zufallswert ca. 16 Bytes groß, kann mit Delphi Random() erzeugt werden
SKey = Sessionkey der als Key für die Verschlüsselung benutzt wird
wir bilden
Salt := Random();
SKey := SHA1(Salt || Key);
Dateiaufbau
H || C
Header || Salt || SKey || Message
H ist unverschlüsselt
C wird sequentiell verschlüsselt mit Blowfish und SKey, dabei MUSS ein FeedbackModus benutzt werden.
Nun, unser Salt ist zufallig und somit wird SKey = SHA1(Salt || Key)
1.) ebenfalls pseudozufällig sein, und
2.) das Userpasswort Key vor Komprimitierung schützen
C, die Nachricht, wird am Anfang mit dem SKey expandiert. Da wir einen Cipher mit Feedbackmodus benutzen wird jeder zu verschlüsselnde Block mit dem verschlüsselten Vorgängerblock verknüpft. Dies ist nun wichtig, denn unser SKey in C ist ja ebenfalls Pseudozufällig. Damit ist der 1. Block im Feedbackmodus des Cipher sozusagen zufällig basierend auf dem Salt + Key. Dieser 1. Block hat direkten Einfluß auf die verschlüsselungen jedes nachfolgenden Message-Blockes.
Lesbar in der Datei stehen also Header + Zufalls Salt. Nur mit dem richtigen Passwort kann man den SKey erzeugen, der mit gleichbleibendem Userpasswort Key denoch IMMER pseudozufällig sein wird. D.h. werden die gleichen Daten mit dem selben Key mehrmals verschlüsselt so sind deren Resultate IMMER unterschiedlich, auf grund des Salts.
Bei einer Entschlüsselung fragt man Key beim User ab, liest Salt aus Datei, erzeugt SKey = SHA1(Salt || Key), initialisiert Blowfish mit Passwort SKey, entschlüsselt aus C den SKey', und vergleicht diesen mit SKey = SKey'. Sollten beide gleich sein so wurde die Datei mit Key verschlüsselt. Nun kann man aus C die Message entschlüsseln.
Ein Angreifer kann nun nur noch eine Brute Force Attacke durchführen. Alle anderen Attacken, wie Known Plain Text, Reply Attacks usw. sind mit hoher Wahrscheinlichkeit ausgeschlossen, da über den Zufalls-Salt sowohl das Userpasswort Key als auch die Verschlüsselung von C über dessen Expandierung mit SKey, randomisiert wurde. Wichtig dabei ist es das C in einem Rutsch mit Hilfe eines BlockCipher und einem Feedback Ciphermode, verschlüsselt wurde.
Bei einer Brute Force Attacke, in der ja nach Key gesucht wird, wird er Angreifer alle möglichen Key's durchprobieren, den Salt auslesen, SKeyTest = SHA1(Salt || TestKey) berechnen und die ersten 20 Bytes aus C entschlüsseln. Sind diese 20 Bytes gleich SKeyTest, dann hat er mit hoher Wahrscheinlichkeit Key = KeyTest gefunden, und kann den Rest der Nachricht entschlüsseln.
Man sieht also das das ganze Konstrukt nur die vielen möglichen Attacken verhindert, aber immer noch absolut von der Qualität vom Key abhängt. Andereseits kann man logisch erkennen das obiges Konstrukt in keinster Weise die Sicherheit der Einzelkomponenten reduziert, also schwächt. Ein Key wie "A" ist also in jedem Falle unsicher, da helfen auch keinerlei Tricks, Kniffe oder Super-Algorithmen.
Um noch mehr Sicherheit zu erreichen muß man an der PKI arbeiten, sprich Schlüssel Infrastruktur. Würde man mit Public Keys arbeiten so würde man Key selber aus Zufall erzeugen und ihn verschlüsselt, durch den Public Key, in der Datei speichern. Nur wer den Privaten Schlüssel besitzt kann diesen Zufalls-Key aus der Datei entschlüsseln. Selbst wenn der Private Schlüssel durch das Passwort "A" geschützt wäre, wäre dieses System denoch sicherer. Denn, der Private Schlüssel steht nur auf Rechnern bzw. Medien zur Verfügung die nur dem berechtigten Benutzer zugänglich sind.
Gruß Hagen