6 Stimmen

Salt ein Schlüssel für sichere Verschlüsselung Cocoa?

Ich habe eine Anleitung gelesen, wie man einen Schlüssel salzt, um die Verschlüsselung sicherer zu machen, konnte aber nicht viel damit anfangen. Ich weiß nicht viel über Kryptographie und brauche etwas Hilfe. Ich benutze commoncrypto, um Dateien zu verschlüsseln, und bin fertig, außer der Tatsache, dass es nicht sicher ist...

Das habe ich:

- (NSData *)AES256EncryptWithKey:(NSString *)key
{
   // 'key' should be 32 bytes for AES256, will be null-padded otherwise
   char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
   bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)

    NSLog(@"You are encrypting something...");

   // fetch key data
   [key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];

   NSUInteger dataLength = [self length];

   //See the doc: For block ciphers, the output size will always be less than or 
   //equal to the input size plus the size of one block.
   //That's why we need to add the size of one block here
   size_t bufferSize = dataLength + kCCBlockSizeAES128;
   void *buffer = malloc( bufferSize );

   size_t numBytesEncrypted = 0;
   CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128,     kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesEncrypted );
   if( cryptStatus == kCCSuccess )
   {
      //the returned NSData takes ownership of the buffer and will free it on deallocation
  return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];

   }

   free( buffer ); //free the buffer
   return nil;
}

Wenn mir jemand helfen kann und mir genau zeigt, wie ich Salz einsetze, wäre das großartig! Nochmals vielen Dank!

15voto

Ivo Punkte 5370

DYhG9pQ1qyJfIxfs2guVoU7jr9oniR2GF8MbC9mi

Text verschlüsseln

Das heißt, sie werden durcheinander geworfen, um sie unleserlich zu machen. Das ist das Spiel, das man in der Kryptographie spielt. Zu diesem Zweck verwendet man deterministische Funktionen.

Verschlüsseln von beinhaltet die Verwendung einer Funktion, die zwei Parameter benötigt: normalerweise einen kurzen Parameter fester Länge und einen Parameter beliebiger Länge. Sie erzeugt eine Ausgabe in der gleichen Größe wie der zweite Parameter.

Der erste Parameter wird als Schlüssel bezeichnet, der zweite als Klartext und die Ausgabe als Chiffretext.

Diese hat eine inverse Funktion (die manchmal dieselbe ist), die dieselbe Signatur hat, aber statt des Chiffretextes den Klartext zurückgibt (bei Verwendung desselben Schlüssels).

Eine gute Verschlüsselungsfunktion zeichnet sich dadurch aus, dass der Klartext ohne Kenntnis des Schlüssels nicht ohne weiteres aus dem Geheimtext ermittelt werden kann. Eine noch bessere Funktion erzeugt einen Chiffretext, der nicht von zufälligem Rauschen zu unterscheiden ist.

Hashing beinhaltet eine Funktion, die einen Parameter beliebiger Größe annimmt und eine Ausgabe fester Größe zurückgibt. Hier ist das Ziel, dass es angesichts einer bestimmten Ausgabe schwer sein sollte, eine jede Eingabe, die sie erzeugt. Es handelt sich um eine Einwegfunktion, die also keine Umkehrung hat. Auch hier ist es großartig, wenn die Ausgabe völlig zufällig aussieht.

Das Problem mit dem Determinismus

Das ist alles sehr schön und gut, aber wir haben ein Problem mit unserem Endziel der Unentzifferbarkeit, wenn wir Implementierungen dieser Funktionen entwerfen: Sie sind deterministisch! Das ist nicht gut für die Erzeugung zufälliger Ausgaben.

Wir können zwar Funktionen entwerfen, die dennoch eine sehr zufällig aussehende Ausgabe erzeugen, dank der Verwirrung und Diffusion Sie werden bei gleichem Input immer noch das gleiche Ergebnis liefern. Wir brauchen das, und wir mögen es nicht. Mit einem nicht-deterministischen Kryptosystem würden wir nie etwas entschlüsseln können, aber wir mögen keine wiederholbaren Ergebnisse! Wiederholbar bedeutet analysierbar... bestimmbar (hm). Wir wollen nicht, dass der Feind dieselben zwei Chiffretexte sieht und weiß, dass sie von derselben Eingabe stammen, denn das würde ihm Informationen liefern (und nützliche Techniken zum Brechen von Kryptosystemen, wie Regenbogentische ). Wie können wir dieses Problem lösen?

Eingabe: einige zufällige Dinge, die am Anfang eingefügt wurden.

So besiegen wir ihn! Wir fügen vor (oder manchmal besser: an), einige einzigartig zufällige Eingabe mit unserer tatsächlichen Eingabe, jedes Mal wenn wir unsere Funktionen verwenden. Dies führt dazu, dass unsere deterministischen Funktionen unterschiedliche Ausgaben liefern, selbst wenn wir dieselbe Eingabe machen. Wir senden die einmalige Zufallseingabe (beim Hashing als Salt, beim Verschlüsseln als Initialisierungsvektor oder IV bezeichnet) zusammen mit dem Chiffretext. Es ist nicht wichtig, ob der Gegner diese zufällige Eingabe sieht; unsere eigentliche Eingabe ist bereits durch unseren Schlüssel (oder den Einweg-Hash) geschützt. Das Einzige, worum wir uns eigentlich Sorgen gemacht haben, ist, dass unsere Ausgabe immer anders ist, so dass sie nicht analysiert werden kann; und das haben wir erreicht.

Wie kann ich dieses Wissen anwenden?

OK. Jeder hat also seine App, und darin sein Kryptosystem, das Teile der App schützt.

Wir wollen das Rad mit Kryptosystemen nicht neu erfinden (Schlechteste Idee aller Zeiten), also haben einige wirklich sachkundige Leute bereits gute Komponenten entwickelt, mit denen jedes System aufgebaut werden kann (z.B. AES, RSA, SHA2, HMAC, PBKDF2). Aber wenn alle dieselben Komponenten verwenden, dann führt das immer noch zu einer gewissen Wiederholbarkeit! Wenn jeder in seinem eigenen Kryptosystem unterschiedliche Schlüssel und eindeutige anfängliche zufällige Eingaben verwendet, sollte das zum Glück kein Problem darstellen.

Jetzt reicht es aber! Sprechen Sie über die Umsetzung!

Lassen Sie uns über Ihr Beispiel sprechen. Sie wollen eine einfache Verschlüsselung durchführen. Was brauchen wir dafür? Nun, A) brauchen wir einen guten Zufallsschlüssel, und B) brauchen wir eine gute Zufalls-IV. Das macht unseren Chiffriertext so sicher wie nur möglich. Wie ich sehe, haben Sie keine Zufalls-IV angegeben - das ist eine gute Übung. Holen Sie sich ein paar Bytes von einer [sicheren/kryptografischen] Zufallsquelle und werfen Sie sie hinein. Sie speichern/senden diese Bytes zusammen mit dem Chiffretext. Ja, das bedeutet, dass der Chiffretext eine konstante Länge größer ist als der Klartext, aber das ist ein kleiner Preis, der zu zahlen ist.

Und was ist mit dem Schlüssel? Manchmal wollen wir einen Schlüssel, den man sich merken kann (wie ein Passwort), und nicht einen netten Zufallsschlüssel, den Computer mögen (wenn Sie die Möglichkeit haben, nur einen Zufallsschlüssel zu verwenden, tun Sie das). Können wir einen Kompromiss finden? Ja! Sollten wir ASCII-Zeichen-Passwörter in Bytes übersetzen, um den Schlüssel zu erstellen? AUF GAR KEINEN FALL!

ASCII-Zeichen sind nicht sehr zufällig (im Allgemeinen werden nur etwa 6-7 von 8 Bits verwendet). Wenn überhaupt, dann sollten wir unseren Schlüssel mindestens siehe zufällig. Wie machen wir das? Nun, Hashing ist zufällig gut dafür geeignet. Was, wenn wir unseren Schlüssel wiederverwenden wollen? Dann erhalten wir denselben Hash... Wiederholbarkeit!

Glücklicherweise verwenden wir die andere Form der einzigartigen Zufallsinputs - ein Salz. Erstellen Sie ein eindeutiges Zufallssalz und hängen Sie es an Ihren Schlüssel an. Dann hacken Sie ihn. Verwenden Sie dann die Bytes, um Ihre Daten zu verschlüsseln. Fügen Sie das Salt UND die IV zusammen mit Ihrem Chiffretext hinzu, wenn Sie ihn senden, und Sie sollten in der Lage sein, ihn am Ende zu entschlüsseln.

Fast fertig? NEIN! Sehen Sie die Hashing-Lösung, die ich im obigen Absatz beschrieben habe? Real Kryptographen würden es als amateurhaft . Würden Sie einem System vertrauen, das dilettantisch ist? Nein! Werde ich erörtern, warum es dilettantisch ist? Nein, denn das brauchen Sie nicht zu wissen. Im Grunde ist es einfach nicht WIRKLICH-SUPER-SCRAMBLED genug für ihren Geschmack.

Sie sollten wissen, dass sie bereits ein besseres System für genau dieses Problem entwickelt haben. Es heißt PBKDF2 . Finden Sie eine Implementierung davon und [lernen Sie], diese stattdessen zu verwenden.

Jetzt sind alle Ihre Daten sicher.

1voto

tgt Punkte 1288

Beim Salzen wird lediglich eine zufällige Zeichenfolge an das Ende des Eingabeschlüssels angehängt.

Erzeugen Sie also eine zufällige Zeichenkette mit einer gewissen Länge:

Erzeugen einer zufälligen alphanumerischen Zeichenfolge in Kakao

Und dann hängen Sie es einfach an den Schlüssel an:

NSString *saltedKey = [key stringByAppendingString:salt];

Sofern Salz in dem von Ihnen gelesenen Artikel nicht anders verwendet wird, sollte dies korrekt sein.

1voto

Kevin Stricker Punkte 16910

Wie ein Zufallssalz normalerweise verwendet wird:

@Ca1icoJack hat völlig Recht, wenn er sagt, dass man nur einige zufällige Daten generieren und an das Ende anhängen muss. Die Daten sind jedoch in der Regel binär und nicht alphanumerisch. Das Salt wird dann unverschlüsselt neben jedem gehashten Kennwort gespeichert und mit dem Klartextkennwort des Benutzers verknüpft, um den Hash bei jeder Eingabe des Kennworts zu überprüfen.

Was nützt ein SALT, wenn es unverschlüsselt neben dem gehashten Passwort gespeichert wird?

Angenommen, jemand erhält Zugang zu Ihren gehashten Kennwörtern. Von Menschen gewählte Passwörter sind ziemlich anfällig dafür, über Rainbow-Tabellen entdeckt zu werden. Die Hinzufügung eines Hashes bedeutet, dass die Rainbow-Tabelle nicht nur die Werte aller möglichen Kombinationen alphanumerischer Zeichen enthalten muss, die eine Person verwenden könnte, sondern auch das zufällige binäre Salt, was zum jetzigen Zeitpunkt ziemlich unpraktisch ist. Das Hinzufügen eines Salt bedeutet also, dass ein Brute-Force-Angreifer, der sowohl auf das gehashte Passwort als auch auf das Salt zugreifen kann, herausfinden muss, wie das Salt mit dem Passwort verknüpft wurde (normalerweise vorher oder nachher) y jedes Kennwort einzeln zu erzwingen, da leicht verfügbare Regenbogentabellen keine binären Zufallsdaten enthalten.

Edit: Aber ich sagte verschlüsselt, nicht gehasht:

Okay, ich habe nicht sehr genau gelesen, ignorieren Sie mich. Jemand muss den Schlüssel mit Gewalt erzwingen, unabhängig davon, ob er verschlüsselt oder nicht verschlüsselt ist. Der einzige erkennbare Vorteil, den ich sehen kann, wäre, wie in dem Artikel beschrieben, zu vermeiden, dass derselbe Schlüssel (aus der Sicht des Benutzers) zur Verschlüsselung derselben Daten verwendet wird und dasselbe Ergebnis liefert. Das ist bei der Verschlüsselung aus verschiedenen Gründen nützlich (verschlüsselte Nachrichten haben in der Regel sich wiederholende Teile, die dazu verwendet werden könnten, die Verschlüsselung leichter zu knacken), aber die Kommentatoren haben Recht, wenn sie anmerken, dass es in diesem Fall normalerweise nicht als Salt bezeichnet wird.

Unabhängig davon, der Trick es um das Salz zu verketten und es neben jedem Bit der verschlüsselten Daten zu speichern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X