2017-01-02 14 views
2

So möchte ich eine Möglichkeit, ein Authentifizierungstoken zu generieren, um es an den Client zurückgeben, so dass es dann verwenden kann, um mit jeder Anfrage zu übergeben.Erzeuge total einzigartige Token, die nie mit php verwendet wurden

Was ist jedoch die beste Methode zum Generieren von einzigartigen Tokens, die noch nie zuvor verwendet wurden.

Ich muss die Eindeutigkeit garantieren, so dass ich es nicht vollständig auf dem PHP uniqid() basieren kann, da es eine minimale Möglichkeit gibt, dass zwei Benutzer zur genau gleichen Zeit anmelden (wirklich kleine Chance, aber diese Chance nicht nutzen können).

Ist es eine schlechte Übung, einen uniqid() Wert mit ihrem Benutzernamen voranzuzählen?

Auch ist der Zeitstempel, der uniqid() basiert auf anfällig für doppelte Werte, wenn Uhren zurück/vorwärts gehen?

Antwort

0

Eine Menge läuft darauf hinaus, wie lange der Code werden kann, wie schwer Sie es brauchen, um einzigartig zu sein, wie schwer es zu unvorhersehbar sein muss, und wenn Sie eine Liste von gültigen Codes haben.

Länge

Erste-off: einfache mathematische impliziert, dass, wenn Sie eine unendliche Anzahl von eindeutigen zufälligen Zeichenfolgen in der Lage sein zu erzeugen, die einzigartig sind, dass Sie die Länge nicht begrenzen kann der Zeichenfolge (It‘ Ich werde unendlich ...).

Wenn Sie die verwendeten Werte in einer Datenbank speichern müssen, benötigt man normalerweise eine maximale Länge.

Unabhängig, unbegrenzte Länge Saiten schaffen eine Menge Gefahren.

wie einzigartig?

Offensichtlich ist die Verwendung der Zeit nicht sehr einzigartig, aber Sie können Dinge hinzufügen, um Kollisionen immer unwahrscheinlicher zu machen, was die Vorhersage erschwert.

Wenn Sie eine Liste von (aktuell) gültigen Codes haben, können Sie den generierten Code immer gegen die vorhandene Datenbank validieren und einen neuen generieren, falls eine Kollision mit einer aktuell gültigen auftreten sollte.

Offensichtlich ein einfaches ständig steigenden Zähler Einzigartigkeit garantieren, aber es ist nicht praktisch, da es nicht Länge begrenzt ist, extrem vorhersehbar usw.

hart

Typischerweise Authentifizierungscodes vorherzusagen, die erraten werden könnte sind schreckliche Sicherheitsidee. Sie müssen sich dagegen wehren.

alles

Kombination, um alles zu kombinieren, können Sie eine Verkettung einer Zeichenfolge erstellen:

  • Eine feste, aber geheime Zeichenfolge (es lang) halten es für eine Passphrase, die macht Ihre Eingabe extrem hart
  • IP-Adresse des Clients
  • verwendete Portnummer vom Client
  • tim erraten e & Datum
  • eine Pseudozufallszahl
  • die Zeichenfolge der Client selbst
  • Benutzername
  • ...

Sie müssen alle nehmen, etc., um die Reihenfolge nicht zu identifizieren verwendet liegt ganz bei dir. Je mehr, desto besser.

Sobald Sie diese Zeichenfolge haben, wählen Sie eine Hash-Funktion, je länger die Ausgabe des Hash, desto weniger wahrscheinlich Kollisionen werden, aber desto mehr Speicher wird der Code in Ihrer Datenbank verwenden.

Eine gute Wahl wäre heutzutage Sha-1 oder Sha-256 (MD5 ist ein bisschen zu kaputt, um in irgendetwas Neuem verwendet zu werden).

Dies gibt Ihnen einen Code, der in der Länge festgelegt ist, ändert sich dramatisch, selbst wenn Sie nur ein Bit in der Eingabe ändern, ist nahezu unmöglich für einen Angreifer vorhersagen und hat eine geringe Chance, eine Kollision zu verursachen.

Wie klein? Es ist extrem unwahrscheinlich, siehe die Mathematik hier: https://crypto.stackexchange.com/questions/24732/probability-of-sha256-collisions-for-certain-amount-of-hashed-values

Wenn Sie die Möglichkeit vollständig ausschließen müssen und keine unbegrenzte Länge von Codes erlauben, können Sie es nur gegen die verwendeten Codes überprüfen und sollte es gefunden werden, können Sie generieren ein neuer.

TL; DR

können Sie andere Dinge hinzufügen, abgesehen von der Zeit, z.B. IP-Adresse der Remote-Seite der Verbindung, Pseudo-Zufallszahl, Prozess-ID, eine feste Zeichenfolge, die Sie geheim halten, etc. mixen Sie diese und machen Sie einen Hash unter Verwendung von z. sha-256 und Sie haben eine feste Länge schwer vorhersagbaren Code.

Das Risiko von Kollisionen besteht, aber es ist enorm klein, wenn Sie es genügend Eingabe geben, um es zu beseitigen: überprüfen Sie gegen die Liste der verwendeten Codes.

+0

Dies ist wirklich hilfreich! Danke :) – Michael

+0

Dachte darüber ein bisschen mehr und eine letzte Frage. Ich möchte, dass das Token für diesen Benutzer garantiert eindeutig ist. Ist es eine schlechte Praxis, die Benutzer-ID (nicht den Benutzernamen, aber das einzigartige automatische Inkrement int) dem Ende des Tokens voranzuzählen, wird dies garantieren, dass das Token niemals von a wiederverwendet werden kann anderer Benutzer. Nur ein bisschen vorsichtig, wenn ein Token aktualisiert wird, aber nicht korrekt an die Client-App übergeben wird und der Client versucht, erneut eine Verbindung herzustellen (sehr geringe Wahrscheinlichkeit, dass es passiert), ein anderer Client-Benutzer hat sein Token aktualisiert und weil das Token nicht 't existiere in der db nicht mehr .... – Michael

+0

....., dieser neue Client erhält den gleichen Token Wert auf die Chance, aber dann versucht die Client-App, die nicht das aufgefrischte Token wieder zu verbinden und Da dieser Client jetzt denselben Token hat, da dieser andere Benutzer nun Zugriff auf dieses andere Benutzerkonto hat, ist die Wahrscheinlichkeit gering, aber ich muss alle Anstrengungen unternehmen, um einen möglichen unbefugten Zugriff zu verhindern. Hoffe, das ist klar – Michael

0

Ich vermute, Sie haben bereits eine Datenbank, wo Sie diese Tokens speichern, so dass Sie überprüfen können, ob es eine richtige ist oder nicht. Wenn das wahr ist, können Sie das Token einfach so generieren, wie Sie es bevorzugen (z. B. uniqid(), zufällige Zeichenfolge, ... was immer Sie möchten) und prüfen, ob das bereits in der db existiert. Wenn es nicht existiert, ist es gut, damit zu gehen, ansonsten können Sie einen neuen erstellen und die Überprüfung erneut durchführen.

+0

Dachte darüber, würde aber die Datenbank ein wenig anstrengen, indem sie jedes Mal, wenn ein neues Token generiert wird, eine Kontrolle über potenziell 1 Millionen Benutzer durchführt. Aber das ist meine Rückfalllösung, wenn ich nicht herausfinden kann, wie man einen Token auf dem Zeitstempel basiert, sowie einen eindeutigen Wert, z. Nutzername. – Michael

+0

Das Anhängen oder Voranstellen des Benutzernamens an den Zeitstempel sollte funktionieren, vielleicht können Sie ihn sogar hashen, damit er nicht leicht lesbar ist. –

+0

Ich denke, wenn ich es Hashes obwohl es anfälliger für Kollisionen sein kann, ist es mehr einzigartig, den Wert des Zeitstempels und Benutzernamen zu verwenden, aber ich möchte nicht den Benutzernamen senden – Michael

-3

Diese Methode funktioniert für mich ...

$token = md5(date['u']); 

Verwendet Anzahl der Sekunden seit der Epoche (1. Januar 1970), um fast eine Garantie Sie einen einzigartigen einmaligen Wert. MD5 verwandelt das in eine 32 Zeichen lange Zeichenfolge. Die Wahrscheinlichkeit von zwei identischen Werten ist immer noch nicht ganz Null, aber extrem nahe bei Null.

Die Verwendung des Datums mit dem Parameter 'u' ist aufgrund der Sommerzeit kein Problem.

+0

Erstens, das ist nicht garantiert, eine eindeutige ID zu liefern, da es nicht nur möglich ist, aber tatsächlich ziemlich wahrscheinlich, dass zwei oder mehr (vielleicht viele mehr!) Benutzer melden sich innerhalb einer Sekunde an, wodurch das gleiche Token generiert wird. Zweitens ist es theoretisch möglich (obwohl unwahrscheinlich), dass zwei * verschiedene * Daten die gleiche MD5-Summe ergeben. – Kjartan

0

Sie könnten eine UUID, Universally Unique IDentifier verwenden. Die technischen Daten sind rfc4122.

Ein Auszug:

Einer der Hauptgründe für die UUID ist, dass keine zentrale Autorität, sie zu verwalten erforderlich ist (obwohl ein Format IEEE 802 Knotenkennungen verwendet, andere nicht). Als Ergebnis kann die Generation auf Anforderung vollständig automatisiert werden und für eine Vielzahl von Zwecke verwendet werden. Der hier beschriebene UUID-Generierungsalgorithmus unterstützt sehr hohe Zuweisungsraten von bis zu 10 Millionen pro Sekunde pro Maschine, wenn notwendig ist, so dass sie sogar als Transaktions-IDs verwendet werden könnten.

UUID-Generatoren

Es gibt UUID-Generatoren für verschiedene Sprachen, sondern nur die Implementierung sicherstellen, dass die Algorithmen in der RFC-4122-Spezifikation verwendet. Viele von ihnen verwenden einfach eine Zufallszahl für jedes Hexoktett der UUID, was zu Kollisionen führen wird.

+0

Danke, irgendwelche Beispielbibliotheken für PHP? – Michael

+0

Sie können die uniqid-Funktion verwenden. http://php.net/manual/en/function.uniqid.php. Es generiert eine eindeutige Zeichenfolge basierend auf der aktuellen Zeit in Mikrosekunden –

Verwandte Themen