Implementierung einer sicheren, einzigartigen "single-use" - Aktivierung URLs in ASP.NET (C#)
Habe ich ein Szenario Iuno Benutzer von einer Website, die ich am Gebäude müssen die Möglichkeit haben, geben Sie einige grundlegende Informationen in einer Web Form-ohne Anmeldung. Die Website ist entwickelt mit ASP.NET/C# und MSSQL 2005 für Ihre relationalen Daten.
Den Benutzer gesendet werden eine E-Mail von der Website, indem Sie Ihnen einen eindeutigen link, um geben Sie die spezifischen Informationen, die Sie benötigt. Die E-Mail sehr ähnlich zu den Stil der email, die wir alle erhalten bei der Registrierung für sites wie Foren, enthält eine zufällig generierte, eindeutige URL-Parameter insbesondere in Bezug auf einen einzigen Zweck (z.B. überprüfen von E-Mail-Adresse für ein forum).
Meine Fragen sind in Bezug auf die sichere Implementierung dieses Problems. Ich überlegte, mit einer GUID als eindeutige Kennung, bin aber unsicher, seine Auswirkungen auf die security world.
- Eine GUID ist ausreichend lang, so dass die Werte nicht leicht zu erraten ist (oder brute-gezwungen, im Laufe der Zeit)?
-
Ist .NET-GUID-Implementierung ausreichend zufällig in dem Sinne, dass es eine gleiche chance der generation, die die möglichen Werte in dem "key space"?
-
Wenn Sie eine GUID ist ein akzeptabler Ansatz, sollte die Seite dann umleiten, um die Informationen über URL-rewriting oder indem die Daten in eine datatable mit der GUID als Referenz?
-
Wird die Verwendung einer URL-rewriting verbergen die wahre Quelle der Daten?
-
Sollte ich in Betracht ziehen mithilfe der TSQL-SELECT NEWID() als GUID-generator über die .NET-Implementierung?
-
Bin ich völlig falsch mit meinem Ansatz zu diesem problem?
Vielen Dank,
Carl
Du musst angemeldet sein, um einen Kommentar abzugeben.
RNGCryptoServiceProvider
) zu erzeugen, das 16 zufällige bytes und initialisiert einGuid
Struktur mit, dass.goto 2
Guid.NewGuid
. Alle I-Sorgfalt über die GUID-format. Erzeugen Sie 16 beliebige bytes mit einem random number generator und pack es in einen GUID-format. Ja, es kann nicht dienen als "Globally Unique Identifier", aber das spielt keine Rolle. GUID format ist nur ein zweckmäßiges format.Was Sie verwenden sollten, anstatt eine GUID ist eine kryptographisch starke Zufallszahlen-generator - Verwendung System.Sicherheit.Die Kryptographie.RNGCryptoServiceProvider, erzeugen lange (sagen wir mal 32 Byte) string-Daten, dann base64-Kodieren, dass.
Auch, vorausgesetzt, es ist eine Art Registrierung mit sensiblen Daten, die Sie wollen, um die Frist der Gültigkeit des Links, sagen, 60 Minuten oder 24 Stunden - hängt von Ihrem Standort.
Halten Sie eine Zuordnung dieser Werte zu bestimmten Benutzern. Dann können Sie automatisch, ihm die richtige form, wie gebraucht. Brauchen nicht zu tun, url-rewriting, nur für die Verwendung der Benutzer-id (auf dieser Seite).
Natürlich, vergessen Sie nicht, dieses URL HTTPS...
Btw, nur ein Hinweis - die gute Praxis zu setzen irgendeine form von text in der E-Mail erklärt, dass Nutzer nicht auf links klicken, die in anonymen E-Mails, und in der Regel Ihre Website nicht senden, und Sie sollten niemals Ihr Kennwort eingeben, nach einem Klick auf blablabla....
Oh, fast vergessen - ein weiteres Problem, sollten Sie überlegen, was passiert, wenn der Benutzer möchte mehrere E-Mails geschickt, um ihn, z.B. trifft register mehrfach. Kann er dies tun, immer und immer wieder, und bekommen viele gültige URLs? Ist nur das Letzte gültig? Oder vielleicht den gleichen Wert bekommt, ärgern sich immer und immer wieder? Natürlich, wenn ein anonymer Benutzer kann in einer Anforderung für das E-Mail, dann DoS kann zu einem Problem werden... nicht zu erwähnen, dass, wenn er führt seine eigene E-Mail -, er kann in jeder beliebigen Adresse auch überschwemmungen, einige schlechte shmuck Posteingang und verursacht möglicherweise Ihre E-mail-server auf schwarze Liste...
Keine richtige Antwort, aber berücksichtigt werden muss, im Kontext Ihrer Anwendung.
Es wäre des guten zuviel, aber das könnte man hash-Ihre E-Mail-Adresse mit SHA1 mit dem guid (NewGuid ist in Ordnung) als hash-Salz und Ort, die in der URL. Dann, wenn Sie kommen zu Ihrer Seite, könnten Sie Sie bitten, Ihre E-Mail-Adresse abrufen der guid und berechnen den hash zu validieren. Auch wenn jemand zu wissen, was E-Mail-Adressen, um zu versuchen, Sie würde nie in der Lage sein zum generieren einer hash-Kollision, ohne zu wissen, die guid, die Sie gesalzen mit (oder es würde Ihnen noch ein verdammt lange Zeit :). Natürlich müssten Sie speichern Ihre E-Mail-und der hash-Salz-guid in der Datenbank.
Ich würde empfehlen, nur mit einem einfachen zufällige Zahl, z.B. bytes aus RNGCryptoServiceProvider.GetBytes . GUIDs sind nicht dazu gedacht völlig zufällig zu sein. Sie haben Feste bits, und einige Versionen verwenden Sie Ihre MAC-Adresse. GetBytes gibt Ihnen auch die Möglichkeit, mehr als 128 bit (obwohl, die sollte reichlich).
Ich denke, es ist besser, nicht zu den Benutzerdaten in einer url. Obwohl HTTPS schützen kann es im transit, kann es immer noch im browser des Benutzers Geschichte oder so. Es ist besser, POST -, und ordnen Sie die zufällige Zahl mit einer Zeile der Datenbank.
Erste, wenn möglich sollte man die Grenze von brute-force, durch die Begrenzung der Durchsatz der Abfrage (z.B. eingeschränkte versucht pro IP pro Sekunde, und die begrenzte Gesamtzahl der versuche pro Sekunde).
Je nach der GUID-Generierung Algorithmus, dies möglicherweise keine gute Idee. Während die aktuellen Implementierungen sollten "gut genug" in der Regel", es kann eine Menge von Vorhersagbarkeit der Werte. Neuere Implementierungen, die man verwendet .NET anwenden einer hash, sonst haben Sie eindeutig identifizierbar Felder für MAC-Adresse, und die Zeit seit Booten. Allerdings sind die möglichen Werte beschränkt sind, so dass Sie nicht haben wahr, 128 random bit.
Wenn die Sicherheit ist die oberste Priorität, ich würde wählen Sie eine kryptografisch starken Zufallszahlengenerator und bauen einen string aus zufälligen Zeichen. Dies macht auch oyu unabhängig von einer leicht guessable Algorithmus (als guid.ToString() ist leicht als solche identifiziert), für die ein Angriff entdeckt werden könnte in der nahen Zukunft.
Wenn diese Kriterien erfüllt sind, sehe ich kein problem, mit den Schlüssel in der Abfrage-string.
erstellen Sie eine Tabelle in der Datenbank mit einem linkID und ein Datesent Spalte, an der Erzeugung des link senden insert DateTime.Nun in die Tabelle und kehren linkId, legen Sie die linkID als querystring-parameter auf die activationLink. Auf die Belastung des Aktivierungs-Seite ermittelt werden die linkId, und verwenden Sie es, um zu erinnern an eine gespeicherte Prozedur, die zurückkehren wird das Datum übergeben, die correspondin linkId als parameter, wenn Sie das Datum zurück, die Sie hinzufügen können, wie lange der link aktiv bleibt, indem mit der .AddDays()/."AddMonths" diese sind C# - Methoden für datetime. dann vergleichen Sie das Datum, an dem Sie zurück kam, mit dem heutigen Datum. wenn es bestanden hat, deren Länge in Tagen oder Monaten eine Fehlermeldung geben oder anders weiter und Anzeige der Inhalte auf der Seite. Ich sugest Sie halten den Inhalt der Seite in einem panel und legen Sie es vissible = "false" dann nur das panel visible="true", wenn das Datum ist immer noch in Reichweite.