Wie implementiert man AES sicher?

  • C#
  • .NET (FX) 4.0

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von nafets.

    Wie implementiert man AES sicher?

    Guten Mittag,

    ich muss in meinem aktuellen Projekt eine Verschlüsselung implementieren und hatte da mal an AES gedacht. Jedoch habe ich mich noch nie wirklich mit einer Verschlüsselung beschäftigt und hatte jetzt mal eine Idee, wie man es implementieren könnte, weiß aber nicht, ob das so gut / brauchbar / sicher ist :D

    Das Passwort des Users würde ich mit der System.Cryptography.SHA384-Klasse hashen. Btw. wo ist da eigentlich der Unterschied zum CryptoServiceProvider oder zur CNG-Implementation? Ich habe dann ja 48 Byte. Davon würde ich die ersten 16 als IV nutzen und die restlichen 32 als Key. Verschlüsseln würde ich das ganze mit der System.Cryptography.Aes-Klasse. Auch hier habe ich leider keine Ahnung was der Unterschied zum AesCryptoServiceProvider und zur AesManaged-Klasse ist. Würde mich freuen, wenn mir das jemand mal erklären würde :)

    Was haltet ihr denn davon und wie würdet ihr das machen?

    LG :)

    ~ides
    Moin,

    der AesCryptoServiceProvider ist nicht verwaltet und nutzt intern die Microsoft CryptoAPI. AesManaged ist eine komplett verwaltete Implementierung des Algorithmus. Die Performance ist trotzdem nahezu gleich und hängt auch von der Datengröße ab. Bei kleineren ist AesManaged schneller, bei größeren die native Implementierung. Das macht allerdings nur Bruchteile einer Millisekunde aus, also von daher. Die beiden Klassen erben auf jeden Fall von Aes.

    Am Besten wäre es, wenn Du 2 Inputs hättest. Ich habe das damals so implementiert:
    github.com/ProgTrade/nUpdate/b…ration/Core/AesManager.cs

    Nutzt also entsprechend Rfc2898DeriveBytes, um das vom Input jeweils abzuleiten.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Ohne jetzt Eigenwerbung machen zu wollen, kannst Du hier rein schauen:
    PasswordList v2.2
    Die Klasse, die Du suchst, heißt AesCryptor.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hier meine Einlassung zum Thema: Verschlüsseln und Autentifizieren

    (ähm: "Ohne jetzt Eigenwerbung machen zu wollen,..." Solche Floskeln können doch nicht ganz ehrlich gemeint sein, odr? ;) - also stehen wir doch lieber dazu, wenn wir Eigenwerbung machen - ist doch nix schlimmes - im Gegenteil)
    /offTopic
    Mal nur ne Interessenfrage: Wenn ich jetzt bspw. wie ein Browser oder wie Spotify ein Passwort lokal speichern muss, damit es der User nicht bei jedem Start eingeben muss, gibt es doch eigentlich keine wirklich sichere Methode, dies zu tun, oder?
    Normalerweise hasht man es dann.

    Zum AES-Problem:
    Das sollte von der Sicherheit ganz OK sein: Salt + Rfc2898DeriveBytes für Generation von Salt & IV.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „nafets“ ()

    Lokal gespeicherte Passwörter sind nur dann sicher, wenn sie nochmal verschlüsselt wurden. Und auch nur dann, wenn der Schlüssel nicht auch lokal gespeichert wird (das heißt, man muss ein Master-Passwort eingeben).
    Da frage ich mich, wie das Browser typischerweise so machen.

    OffTopic:
    @ErfinderDesRades
    Gemeint war, dass ich nicht "Schau mein cooles Programm an!" sagen will, sondern "Hey, ich hab das schon mal gemacht und das könnte hilfreich für Dich sein.".
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Niko Ortner“ ()

    @Niko Ortner Firefox bietet die Option mit dem Master-Passwort an. Chrome speichert sogar unverschlüsselt im Klartext.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Niko Ortner schrieb:

    wie das Browser typischerweise so machen.

    Trade schrieb:

    Chrome speichert sogar unverschlüsselt im Klartext.
    Sieht nur so aus.
    Der Password-Safe ist mit deinem Windows-Password verschlüsselt.
    Versuch mal die Passworte eines anderen Users zu entschlüsseln.

    howtogeek.com/70146/how-secure…chrome-browser-passwords/
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    ichduersie schrieb:

    ich muss in meinem aktuellen Projekt eine Verschlüsselung implementieren und hatte da mal an AES gedacht. Jedoch habe ich mich noch nie wirklich mit einer Verschlüsselung beschäftigt[...]
    Dann vielleicht zusätzlich beschreiben, was du verschlüsseln möchtest, warum und was mit den Daten passieren soll.

    ichduersie schrieb:

    Ich habe dann ja 48 Byte. Davon würde ich die ersten 16 als IV nutzen und die restlichen 32 als Key.
    Bitte nicht. Der IV muss einmalig sein (*). Ihn mehr als einmal mit dem gleichen Key zu verwenden, macht den Sinn zu nichte. Am besten zufällig (nicht per Random, sondern einen kryptographisch sicheren Zufallszahlengenerator) generieren lassen. Im Framework z.B. mit der Methode GenerateIV aus der AesManaged-Klasse. Niemals deterministisch bestimmen, also bitte auch kein Rfc2898 wo Key und Salt irgendwie vorhersagbar sind.
    Der IV muss nicht geheim sein, den kannst du problemlos unverschlüsselt zusammen mit den verschlüsselten Daten abspeichern/übertragen.

    ichduersie schrieb:

    Wenn ich jetzt bspw. wie ein Browser oder wie Spotify ein Passwort lokal speichern muss, damit es der User nicht bei jedem Start eingeben muss, gibt es doch eigentlich keine wirklich sichere Methode, dies zu tun, oder?
    Das sicherste ohne Zusatz wäre wahrscheinlich dem Benutzer ein (Master)Passwort eingeben zu lassen, welches die anderen Passwörter entschlüsselt. Alles andere dient nur dazu die Latte höher zu legen. (Anbei interessanter Artikel von den Pdigin-Entwicklern, die Speichern das Passwort auf Wunsch im Klartext: developer.pidgin.im/wiki/PlainTextPasswords)

    *) Hängt natürlich vom Algorithmus, dem verwendeten Modus und dem konkreten Szenario ab. Bei AES sollte es meines Wissens zumindest nie schaden, wenn man den IV zufällig wählt... und ein paar mehr Bytes zum Übertragen/Speichern nicht kritisch sind.

    3daycliff schrieb:

    also bitte auch kein Rfc2898 wo Key und Salt irgendwie vorhersagbar sind.
    Aber @Trade beispielsweise hat den Salt sogar in seinem Quellcode gespeichert:

    C#-Quellcode

    1. ​[b][/b]var keyPasswordDeriveBytes = new Rfc2898DeriveBytes(keyPassword, new byte[] {0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84}); var ivPasswordDeriveBytes = new Rfc2898DeriveBytes(ivPassword, new byte[] {0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84});[b][/b][b][/b]
    tl;dr

    Der IV darf nicht aus dem Passwort generiert werden, sondern per Zufallsgenerator. Den IV-Wert dann einfach irgendwo da speichern, wo es passt (bei Protokollen bspw. im Handshake). Das gleiche gilt auch für den Salt.
    Mit freundlichen Grüßen,
    Thunderbolt
    Der Code-Snippet sagt jetzt nicht wirklich viel aus, da unklar ist, wo keyPassword und ivPassword herkommen und was letztlich mit den beiden Rfc2898DeriveBytes-Objekten gemacht wird.

    Sinn vom IV ist es, bei einem Block-Cipher den ersten Block zu randomisieren, so dass zwei, mit dem selben Key, verschlüsselte Texte, nicht den gleichen Ciphertext haben. Wenn diese Eigenschaft nicht wichtig ist (ist sie aber normalerweise), kann man natürlich einen festen IV nehmen bzw. diesen deterministisch bestimmen. Das hängt aber vom konkreten Szenario ab und nur anhand des Auszugs kann man das Szenario nicht feststellen (und die Zeit, um den Datenfluss im verlinkten Quelltext zu analysieren, um festzustellen, ob das ein Problem ist, will ich jetzt nicht unbedingt aufbringen). In aller Regel will man aber diese Eigenschaft haben und entsprechend muss der IV zufällig sein.
    @3daycliff
    Und wenn man für jedes Mal sowieso einen anderen Key & IV generiert, indem man Rfc2898DeriveBytes mit einem zufälligen Salt (wie halt in meinem Snippet) nutzt? Das sollte dann doch auch sicher sein, oder?
    @nafets
    Bitte mich nicht mit einem Experten verwechseln. Bei deinem Ansatz, wenn man Validierung und Authentizität mal beiseite lässt, sehe ich zumindest spontan kein offensichtliches Problem. Das muss aber überhaupt rein gar nichts heißen.

    @ichduersie
    Ich weiß, dass der komplette Code OpenSource ist, aber (ich zitiere mich mal selbst): "die Zeit, um den Datenfluss im verlinkten Quelltext zu analysieren, um festzustellen, ob das ein Problem ist, will ich jetzt nicht unbedingt aufbringen". (Ob ich ein Problem sehen würde, wenn eins vorliegt, sei sowieso mal dahin gestellt.)