it-swarm.com.de

Wie kann ich ein Kennwort am einfachsten verschlüsseln, wenn ich es in der Registrierung speichere?

Momentan schreibe ich es in Klartext Hoppla!, es ist ein internes Programm, also ist es nicht so schlimm, aber ich würde es gerne richtig machen. Wie muss ich vorgehen, um dies beim Schreiben in die Registrierung zu verschlüsseln, und wie kann ich es entschlüsseln?

OurKey.SetValue("Password", textBoxPassword.Text);
57
Lisa

Sie entschlüsseln keine Authentifizierungskennwörter!

Hash sie mit etwas wie dem SHA256-Provider und wenn Sie herausfordern müssen, Hash die Eingabe des Benutzers und sehen, ob die beiden Hashs übereinstimmen.

byte[] data = System.Text.Encoding.ASCII.GetBytes(inputString);
data = new System.Security.Cryptography.SHA256Managed().ComputeHash(data);
String hash = System.Text.Encoding.ASCII.GetString(data);

Passwörter umkehrbar zu lassen ist ein wirklich schreckliches Modell.

Edit2: Ich dachte, wir sprachen nur über Front-Line-Authentifizierung. Sicher, es gibt Fälle, in denen Sie Kennwörter für andere Dinge verschlüsseln möchten, die umkehrbar sein müssen, aber es sollte darüber eine 1-Wege-Sperre geben (mit sehr wenigen Ausnahmen).

Ich habe den Hashing-Algorithmus aktualisiert, aber um die bestmögliche Stärke zu erzielen, möchten Sie ein privates Salz) behalten und das Ihrer Eingabe hinzufügen , bevor Sie hashen es . Sie würden dies erneut tun, wenn Sie vergleichen. Dies fügt eine weitere Ebene hinzu, die es für jemanden noch schwieriger macht, das Bild umzukehren.

123
Oli

Bitte denken Sie auch daran, Ihren Haschisch zu "salzen" (kein kulinarisches Konzept!). Grundsätzlich bedeutet dies, dass Sie dem Kennwort einen zufälligen Text hinzufügen, bevor Sie es haschen.

" Der Salt-Wert verlangsamt einen Angreifer, der einen Wörterbuchangriff durchführt, falls Ihr Anmeldeinformationsspeicher gefährdet ist, und gibt Ihnen zusätzliche Zeit, um die Gefährdung zu erkennen und darauf zu reagieren. "

So speichern Sie Passwort-Hashes:

a) Erzeuge einen zufälligen Salzwert:

byte[] salt = new byte[32];
System.Security.Cryptography.RNGCryptoServiceProvider.Create().GetBytes(salt);

b) Hängen Sie das Salz an das Passwort an.

// Convert the plain string pwd into bytes
byte[] plainTextBytes = System.Text UnicodeEncoding.Unicode.GetBytes(plainText);
// Append salt to pwd before hashing
byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
System.Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
System.Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);

c) Hash das kombinierte Passwort & Salt:

// Create hash for the pwd+salt
System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
byte[] hash = hashAlgo.ComputeHash(combinedBytes);

d) Hänge das Salz an den resultierenden Hash an.

// Append the salt to the hash
byte[] hashPlusSalt = new byte[hash.Length + salt.Length];
System.Buffer.BlockCopy(hash, 0, hashPlusSalt, 0, hash.Length);
System.Buffer.BlockCopy(salt, 0, hashPlusSalt, hash.Length, salt.Length);

e) Speichern Sie das Ergebnis in Ihrer Benutzerspeicherdatenbank.

Dieser Ansatz bedeutet, dass Sie das Salt nicht separat speichern und den Hash dann unter Verwendung des Salt-Werts und des vom Benutzer erhaltenen Klartext-Passwortwerts neu berechnen müssen.

Bearbeiten : Da die rohe Rechenleistung billiger und schneller wird, ist der Wert von Hashing - oder Salting-Hashes - gesunken. Jeff Atwood hat ein exzellentes Update für 2012 zu lang, um es hier vollständig zu wiederholen.

Dies (unter Verwendung von gesalzenen Hashes) wird die Illusion von Sicherheit mehr als jede tatsächliche Sicherheit bereitstellen. Da Sie sowohl den Salt-Algorithmus als auch die Wahl des Hash-Algorithmus benötigen, um den Hash zu generieren und um den Hash zu überprüfen, ist es unwahrscheinlich, dass ein Angreifer den einen, aber nicht den anderen haben würde. Wenn Sie bis zu dem Punkt kompromittiert wurden, an dem ein Angreifer über Ihre Kennwortdatenbank verfügt, können Sie davon ausgehen, dass er über Ihr geheimes, verborgenes Salz verfügt oder dieses erhalten kann.

Die erste Sicherheitsregel lautet, immer das Schlimmste anzunehmen und zu planen. Sollten Sie ein Salz verwenden, idealerweise ein zufälliges Salz für jeden Benutzer? Sicher, es ist definitiv eine gute Praxis, und zumindest können Sie damit zwei Benutzer mit demselben Kennwort unterscheiden. Aber heutzutage kann Salz allein Sie nicht mehr vor einer Person retten, die bereit ist, ein paar tausend Dollar für Grafikkarten-Hardware auszugeben, und wenn Sie glauben, dass dies möglich ist, sind Sie in Schwierigkeiten.

23
DOK

Tom Scott hat es richtig verstanden, wie (nicht) Passwörter auf Computerphile gespeichert werden.

https://www.youtube.com/watch?v=8ZtInClXe1Q

  1. Wenn Sie dies überhaupt vermeiden können, versuchen Sie nicht, Kennwörter selbst zu speichern. Verwenden Sie eine separate, vorab eingerichtete, vertrauenswürdige Benutzerauthentifizierungsplattform (z. B.: = OAuth Anbieter, Active Directory-Domäne Ihres Unternehmens usw.).

  2. Wenn Sie Kennwörter speichern müssen, befolgen Sie keine der hier aufgeführten Anweisungen. Zumindest nicht, ohne auch neuere und seriöse Veröffentlichungen zu konsultieren, die für Ihre Sprache relevant sind nach Wahl.

Es gibt sicherlich eine Menge kluger Leute hier und wahrscheinlich sogar eine gute Anleitung. Die Chancen stehen jedoch gut, dass alle Antworten (einschließlich dieser) bereits veraltet sind, wenn Sie dies lesen.


Der richtige Weg zum Speichern von Passwörtern ändert sich im Laufe der Zeit.

Wahrscheinlich häufiger als manche Leute ihre Unterwäsche wechseln.


Nachstehend einige allgemeine Hinweise, die hoffentlich noch eine Weile nützlich sein werden.

  1. Keine Passwörter verschlüsseln. Jede Speichermethode, die die Wiederherstellung der gespeicherten Daten ermöglicht, ist von Natur aus unsicher Halten von Passwörtern - alle Formen der Verschlüsselung inklusive.
  2. Verarbeiten Sie die Passwörter genau so, wie sie vom Benutzer während des Erstellungsprozesses eingegeben wurden. Alles, was Sie mit dem Passwort tun, bevor Sie es senden Das Kryptografiemodul wird es wahrscheinlich nur schwächen. Wenn Sie eine der folgenden Aktionen ausführen, wird der Prozess zum Speichern und Überprüfen von Kennwörtern ebenfalls komplexer, was später zu anderen Problemen führen kann (möglicherweise sogar zu Sicherheitslücken).

    • Konvertieren Sie nicht in Groß-/Kleinschreibung.
    • Leerzeichen nicht entfernen.
    • Entfernen Sie keine inakzeptablen Zeichen oder Zeichenketten.
    • Ändern Sie die Textcodierung nicht.
    • Ersetzen Sie keine Zeichen oder Zeichenketten.
    • Kürzen Sie keine Passwörter von beliebiger Länge.
  3. Die Erstellung von Kennwörtern, die nicht ohne Änderung gespeichert werden können, ablehnen. Das Obige verstärken. Wenn Ihr Kennwortspeichermechanismus aus irgendeinem Grund bestimmte Zeichen, Leerzeichen, Zeichenfolgen oder Kennwortlängen nicht ordnungsgemäß verarbeiten kann, geben Sie einen Fehler zurück und informieren Sie den Benutzer über die Systembeschränkungen, damit er es erneut mit einem darin enthaltenen Kennwort versuchen kann. Machen Sie für eine bessere Benutzererfahrung eine Liste dieser Einschränkungen für den Benutzer im Voraus zugänglich. Machen Sie sich nicht einmal Sorgen, geschweige denn verstecken Sie die Liste vor Angreifern - sie werden es auf jeden Fall leicht genug selbst herausfinden.

  4. Verwenden Sie für jedes Konto ein langes, zufälliges und eindeutiges Salt. Die Passwörter von zwei Konten sollten niemals gleich aussehen im Speicher, auch wenn die Passwörter tatsächlich identisch sind.
  5. Verwenden Sie langsame und kryptografisch starke Hashing-Algorithmen, die für die Verwendung mit Kennwörtern entwickelt wurden. MD5 ist mit Sicherheit nicht verfügbar. SHA-1/SHA-2 sind no-go. Aber ich werde Ihnen auch hier nicht sagen, was Sie sollten verwenden. (Siehe die erste Nr. 2 in diesem Beitrag.)
  6. Iterieren Sie so viel Sie tolerieren können. Während Ihr System möglicherweise bessere Dinge mit seinen Prozessorzyklen zu tun hat als Hash Passwörter den ganzen Tag haben die Leute, die Ihre Passwörter knacken, Systeme, die dies nicht tun. Machen Sie es ihnen so schwer wie möglich, ohne es Ihnen ganz "zu schwer" zu machen.

Am wichtigsten...

Hören Sie hier niemandem zu.

Suchen Sie in einer seriösen und kürzlich erschienenen Publikation nach den geeigneten Methoden zur Kennwortspeicherung für die Sprache Ihrer Wahl. Tatsächlich sollten Sie mehrere neuere Veröffentlichungen aus mehreren separaten Quellen finden, die übereinstimmen, bevor Sie sich für eine Methode entscheiden.

Es ist sehr wahrscheinlich, dass alles, was alle hier (ich selbst eingeschlossen) gesagt haben, bereits durch bessere Technologien ersetzt oder durch neu entwickelte Angriffsmethoden unsicher gemacht wurde. Geh und finde etwas, das wahrscheinlich nicht ist.

14
Iszi

Das möchten Sie tun:

OurKey.SetValue("Password", StringEncryptor.EncryptString(textBoxPassword.Text));
OurKey.GetValue("Password", StringEncryptor.DecryptString(textBoxPassword.Text));

Dies können Sie mit den folgenden Klassen tun. Diese Klasse ist eine generische Klasse und der Client-Endpunkt. Es ermöglicht IOC verschiedener Verschlüsselungsalgorithmen mit Ninject .

public class StringEncryptor
{
    private static IKernel _kernel;

    static StringEncryptor()
    {
        _kernel = new StandardKernel(new EncryptionModule());
    }

    public static string EncryptString(string plainText)
    {
        return _kernel.Get<IStringEncryptor>().EncryptString(plainText);
    }

    public static string DecryptString(string encryptedText)
    {
        return _kernel.Get<IStringEncryptor>().DecryptString(encryptedText);
    }
}

Diese nächste Klasse ist die ninject-Klasse, mit der Sie die verschiedenen Algorithmen einfügen können:

public class EncryptionModule : StandardModule
{
    public override void Load()
    {
        Bind<IStringEncryptor>().To<TripleDESStringEncryptor>();
    }
}

Dies ist die Schnittstelle, die jeder Algorithmus implementieren muss, um Zeichenfolgen zu verschlüsseln/entschlüsseln:

public interface IStringEncryptor
{
    string EncryptString(string plainText);
    string DecryptString(string encryptedText);
}

Dies ist eine Implementierung mit dem TripleDES-Algorithmus:

public class TripleDESStringEncryptor : IStringEncryptor
{
    private byte[] _key;
    private byte[] _iv;
    private TripleDESCryptoServiceProvider _provider;

    public TripleDESStringEncryptor()
    {
        _key = System.Text.ASCIIEncoding.ASCII.GetBytes("GSYAHAGCBDUUADIADKOPAAAW");
        _iv = System.Text.ASCIIEncoding.ASCII.GetBytes("USAZBGAW");
        _provider = new TripleDESCryptoServiceProvider();
    }

    #region IStringEncryptor Members

    public string EncryptString(string plainText)
    {
        return Transform(plainText, _provider.CreateEncryptor(_key, _iv));
    }

    public string DecryptString(string encryptedText)
    {
        return Transform(encryptedText, _provider.CreateDecryptor(_key, _iv));
    }

    #endregion

    private string Transform(string text, ICryptoTransform transform)
    {
        if (text == null)
        {
            return null;
        }
        using (MemoryStream stream = new MemoryStream())
        {
            using (CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
            {
                byte[] input = Encoding.Default.GetBytes(text);
                cryptoStream.Write(input, 0, input.Length);
                cryptoStream.FlushFinalBlock();

                return Encoding.Default.GetString(stream.ToArray());
            }
        }
    }
}

Sie können mein Video ansehen und den Code dafür herunterladen: http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-inhibernateactive-record-video .html

11
Jamie Wright

Eine Möglichkeit wäre, den Hash (SHA1, MD5) des Passworts anstelle des Klartext-Passworts zu speichern. Wenn Sie sehen möchten, ob das Passwort gut ist, vergleichen Sie es einfach mit diesem Hash.

Wenn Sie einen sicheren Speicher benötigen (z. B. für ein Kennwort, mit dem Sie eine Verbindung zu einem Dienst herstellen), ist das Problem komplizierter.

Wenn es nur zur Authentifizierung dient, reicht es aus, den Hash zu verwenden.

10
Bogdan Maxim

Wenn Sie in der Lage sein möchten, das Kennwort zu entschlüsseln, denke ich, dass der einfachste Weg darin besteht, DPAPI (Benutzerspeichermodus) zum Verschlüsseln/Entschlüsseln zu verwenden. Auf diese Weise müssen Sie nicht mit Verschlüsselungsschlüsseln herumspielen, sie irgendwo speichern oder in Ihrem Code fest codieren - in beiden Fällen kann jemand sie durch Durchsuchen der Registrierung, der Benutzereinstellungen oder mithilfe von Reflector erkennen.

Ansonsten verwende die Hashes SHA1 oder MD5, wie andere hier gesagt haben.

9
liggett78

Wie ligget78 sagte, wäre DPAPI ein guter Weg, um Passwörter zu speichern. Überprüfen Sie die ProtectedData-Klasse auf MSDN zum Beispiel Verwendung.

6
Beau

Ich habe überall nach einem guten Beispiel für den Ver- und Entschlüsselungsprozess gesucht, aber die meisten waren zu komplex.

Trotzdem kann es viele Gründe geben, warum jemand einige Textwerte einschließlich Passwörtern entschlüsseln möchte. Der Grund, warum ich das Passwort auf der Site, an der ich gerade arbeite, entschlüsseln muss, ist, dass sie sicherstellen möchten, dass nach Ablauf dieses Zeitraums niemand gezwungen ist, das Passwort zu ändern, wenn eine nahe Variante desselben Passworts vorliegt Sie haben in den letzten x Monaten verwendet.

Also habe ich einen Prozess geschrieben, der dies auf vereinfachte Weise tun wird. Ich hoffe, dieser Code ist für jemanden von Vorteil. Soweit ich weiß, kann ich dies zu einem anderen Zeitpunkt für ein anderes Unternehmen/einen anderen Standort verwenden.

public string GenerateAPassKey(string passphrase)
    {
        // Pass Phrase can be any string
        string passPhrase = passphrase;
        // Salt Value can be any string(for simplicity use the same value as used for the pass phrase)
        string saltValue = passphrase;
        // Hash Algorithm can be "SHA1 or MD5"
        string hashAlgorithm = "SHA1";
        // Password Iterations can be any number
        int passwordIterations = 2;
        // Key Size can be 128,192 or 256
        int keySize = 256;
        // Convert Salt passphrase string to a Byte Array
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
        // Using System.Security.Cryptography.PasswordDeriveBytes to create the Key
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
        //When creating a Key Byte array from the base64 string the Key must have 32 dimensions.
        byte[] Key = pdb.GetBytes(keySize / 11);
        String KeyString = Convert.ToBase64String(Key);

        return KeyString;
    }

 //Save the keystring some place like your database and use it to decrypt and encrypt
//any text string or text file etc. Make sure you dont lose it though.

 private static string Encrypt(string plainStr, string KeyString)        
    {            
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = 256;
        aesEncryption.BlockSize = 128;
        aesEncryption.Mode = CipherMode.ECB;
        aesEncryption.Padding = PaddingMode.ISO10126;
        byte[] KeyInBytes = Encoding.UTF8.GetBytes(KeyString);
        aesEncryption.Key = KeyInBytes;
        byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);
        ICryptoTransform crypto = aesEncryption.CreateEncryptor();
        byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
        return Convert.ToBase64String(cipherText);
    }

 private static string Decrypt(string encryptedText, string KeyString) 
    {
        RijndaelManaged aesEncryption = new RijndaelManaged(); 
        aesEncryption.KeySize = 256;
        aesEncryption.BlockSize = 128; 
        aesEncryption.Mode = CipherMode.ECB;
        aesEncryption.Padding = PaddingMode.ISO10126;
        byte[] KeyInBytes = Encoding.UTF8.GetBytes(KeyString);
        aesEncryption.Key = KeyInBytes;
        ICryptoTransform decrypto = aesEncryption.CreateDecryptor(); 
        byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length); 
        return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length)); 
    }

 String KeyString = GenerateAPassKey("PassKey");
 String EncryptedPassword = Encrypt("25Characterlengthpassword!", KeyString);
 String DecryptedPassword = Decrypt(EncryptedPassword, KeyString);
6
Deathstalker

Wenn es sich um ein Kennwort handelt, das von Ihrer Anwendung zur Authentifizierung verwendet wird, wird das Kennwort wie von anderen vorgeschlagen gehasht.

Wenn Sie Kennwörter für eine externe Ressource speichern, möchten Sie den Benutzer häufig zur Eingabe dieser Anmeldeinformationen auffordern und ihm die Möglichkeit geben, diese sicher zu speichern. Windows stellt zu diesem Zweck die Benutzeroberfläche für Anmeldeinformationen (CredUI) zur Verfügung. Es gibt eine Reihe von Beispielen, die zeigen, wie dies in .NET verwendet wird, einschließlich dieses Beispiel auf MSDN .

5
Joe

Wenn Sie mehr benötigen, z. B. eine Verbindungszeichenfolge (für die Verbindung mit einer Datenbank), aktivieren Sie dieses Kontrollkästchen Artikel , da es die beste "Option" dafür bietet.

Die Antwort von Oli ist auch gut, da sie zeigt, wie Sie einen Hash für eine Zeichenfolge erstellen können.

1
Bogdan Maxim

..NET stellt Kryptografiedienste in Klassen bereit, die im System.Security.Cryptography-Namespace enthalten sind.

0
osp70