2009-08-06 8 views
5

Przepełnienie stosu Ahoy! To będzie pierwszy post ...Generowanie silnego unikalnego identyfikatora użytkownika w/PHP i MySQL

Próbuję zidentyfikować użytkowników z solonym unikalnym kluczem publicznym.

  1. Algorytm - Czy mogę używać uniqid(), sha256, sha512, coś innego? Wszystkie skróty zostaną zasolone. NIST zalecił SHA256, ale wolę usłyszeć, co inni mogą zasugerować.
  2. Generation - Czy hash (sól + AUTO_INCREMENT_PK + CREATED_TIMESTAMP) wystarczy? Więcej entropii?
    • Korzystałbym z poczty e-mail, ponieważ jest ona unikalna dla każdego użytkownika, jednak użytkownik może modyfikować swój adres e-mail. Rozważałem również przechowywanie konta signup_email, aby skróty nie musiały być ponownie obliczane.
  3. MySQL bagażu - Obecnie nasze ID są INT (255) auto_increment klucz podstawowy jest. Jak wspomniano wcześniej, potencjalnie setki milionów kluczy. W zależności od crypto algo powinienem mieć stały rozmiar. Czy mogę zachować INT (255) czy powinienem użyć CHAR (n)?

---------------------- Thanks for reading :) -------------------------------

+0

Chyba dodatkowy cel: jest ogólna szybkość tego rodzaju systemu będzie lepsza niż przyrostowe liczb całkowitych, a warto prędkość zyskać dodatkowe zabezpieczenie? Czy mam rację, myśląc, że INT może przechowywać efektywnie hex? zgodnie z sugestią woli, myślę, że spróbuję sha256. – brack

Odpowiedz

5

jedno: Jeśli nie ufa użytkownikom ich identyfikatory, wysyłając je przez GET lub POST nie będzie działać; wszystkie są widoczne dla zmotywowanych użytkowników.


użyłbym SHA256 użyciu ciąg salt.counter.time i użyć wyjścia do wygenerowania GUID dla rzeczywistego id. To zminimalizowałoby możliwość kolizji.

Będziesz musiał użyć CHAR dla MySQL do przechowywania identyfikatorów GUID.

Zobacz komentarze na http://us2.php.net/manual/en/function.uniqid.php, aby uzyskać bardziej szczegółowe informacje. AFAIK GUID nie jest częścią jądra PHP, więc musisz go trochę sfałszować.

+0

Hashowanie nie jest konieczne. W rzeczywistości funkcje mieszania nie tworzą unikatowych wartości. – Gumbo

+0

@Gumbo - Nie technicznie, ale za pomocą wysokiej jakości hashu, takiego jak Rijndal z wysokiej jakości wejściem entropii, można użyć skrótu z * astronomicznie * niskimi zderzeniami zbliżonymi do zera. – willoller

+0

To prawie odpowiedź, moje pytanie, ponieważ byłem ciekawy, czy potrzebuję char lub czy mogę zachować INT. Jak wspomniano, astronomicznie mała szansa na kolizję jest w porządku ze mną, ponieważ myślę, że będę miał wystarczającą entropię. Zajrzę też do salt.counter.time. Jeśli produkuję hasze przy zachowaniu niskiego współczynnika kolizji, czy istnieje potencjał, aby nadal używać INT (255) MySQL jako typu danych? – brack

3

Jeśli używasz identyfikatora użytkownika jako sposobu na umożliwienie użytkownikowi zrobienia czegokolwiek z Twoją usługą, jeśli jeden użytkownik "odgadnie" identyfikator innego użytkownika, będzie mógł zrobić, co chce, z tym użytkownikiem konto ?

Nie masz żadnych innych haseł ani niczego, aby to osiągnąć?


Cóż, w takim przypadku trzeba coś zupełnie wyjątkowy, prawda ;-)
(Licząc zrozumiałem pytanie dobrze - ale to nie może być przypadek - przepraszam, jeśli to nie jest)

Co sądzisz o korzystaniu z Globally Unique Identifier (jak na przykład 61350955-9755-4AF3-8C19-6DBC42CA69E2) dla swoich użytkowników?
Na przykład tego, jak one wyglądają, przyjrzeć http://createguid.com/


As sidenote, że GUID jest dość długa; co oznacza wiele bajtów w twoim DB, jeśli masz miliony użytkowników ... Więc prawdopodobnie nie powinien być używany jako klucz podstawowy/zagraniczny.

Co z wykorzystaniem najmniejszej możliwej liczby całkowitej (która pasuje do liczby użytkowników), jako klucza głównego/obcego, ponieważ zostanie ona zduplikowana w wielu miejscach aplikacji; i tylko "długi identyfikator użytkownika" jest przechowywany tylko raz, w tabeli użytkownika?

+0

Hasła istnieją dla użytkowników, tak ... Myślę, że mogłem zagłębić się w nieco głębiej ... Zasadniczo potrzebuję tylko bezpiecznego sposobu na utrzymanie użytkownika w pewnym stopniu bezpiecznego, ale również po to, aby zidentyfikować użytkownika w logice db. Nie mam nic przeciwko osobom, które widzą publiczny identyfikator użytkownika, ponieważ jego identyfikator na poziomie bazy danych jest ukryty i niepowtarzalny. Nie będą także miały dostępu do usługi internetowej i będą wymagały uwierzytelnienia w celu uzyskania dostępu do funkcji, które mogą być niebezpieczne. – brack

+0

Ponadto, cel tego identyfikatora będzie przechowywany tak, jak wspomniano - chcę przechowywać tylko długi identyfikator użytkownika w tabeli rdzenia użytkownika i odwoływać się do niego za pośrednictwem innych tabel użytkowników. Używam inkrementalnego int id, ale chcę zachować to w ukryciu i nigdy go nie ujawniać poza PHP i MySQL. Dzięki – brack

0

Osobiście używam md5 (uniqid (mt_rand(), true)), który utworzy 32-znakowy identyfikator (128-bitową liczbę heksadecymalną), który jest niezwykle trudny do przewidzenia.

1

Napisałem tę klasę, która daje unikalny identyfikator 24 znaków, zgodny z polem id MongoDB (i używając tej samej logiki, aby go skonstruować). Może się przydać w przyszłości.

<?php 
/** 
* Generator for Mongo-like ObjectIds in pure PHP 
* Author: Mauricio Piacentini 
* 
* Inspired by https://github.com/justaprogrammer/ObjectId.js 
* 
*/ 

class ObjectIdFactory 
{ 
    private $_datetime = null; 
    private $_machine = null; 
    private $_pid = null; 
    private $_increment = null; 

    public function __construct() 
    { 
     $this->_machine = str_pad(dechex(rand(0, 16777215)), 6, "0", STR_PAD_LEFT); 
     $this->_pid = str_pad(dechex(rand(0, 32767)), 4, "0", STR_PAD_LEFT); 
     $this->_increment = rand(0, 16777215); 

     //We need a DateTime object to get timestamps, cache it 
     $this->_datetime = new DateTime(); 
    } 

    public function getNewId($forcedincrement = null) 
    { 
     if (is_null($forcedincrement)) { 
      $this->_increment++; 
      if ($this->_increment > 0xffffff) { 
       $this->_increment = 0; 
      } 
     } else { 
      $this->_increment = $forcedincrement; 
     } 
     $timestamp = $this->_datetime->getTimestamp(); 

     $timestamp_final = str_pad(dechex($timestamp), 8, "0", STR_PAD_LEFT); 
     $increment_final = str_pad(dechex($this->_increment), 6, "0", STR_PAD_LEFT); 
     return $timestamp_final . $this->_machine . $this->_pid . $increment_final; 
    } 

} 

https://github.com/piacentini/ObjectId.php

Powiązane problemy