Domanda

Quanto è sicuro da usare UUID per identificare in modo univoco qualcosa (lo sto usando per i file caricati sul server)? A quanto mi risulta, si è basato fuori numeri casuali. Tuttavia, sembra a me che dato abbastanza tempo, si sarebbe poi ripeterlo sé, solo per puro caso. Esiste un sistema migliore o uno schema di un certo tipo per alleviare questo problema?

È stato utile?

Soluzione

Molto sicuro:

  

il rischio annuale di una data persona che viene colpita da un meteorite è   stimata essere una possibilità su 17 miliardi, il che significa che il   probabilità è di circa ,00000000006 (6 × 10 -11 ), equivalente alle probabilità   della creazione di poche decine di bilioni di UUID in un anno e che hanno uno   duplicare. In altre parole, solo dopo che la generazione di 1 miliardo di UUID ogni   secondo per i prossimi 100 anni, la probabilità di creare un solo   duplicare sarebbe di circa il 50%.

Caveat:

  

Tuttavia, queste probabilità tengono solo quando gli UUID vengono generati   utilizzando entropia sufficiente. In caso contrario, la probabilità di duplicati   potrebbe essere significativamente superiore, in quanto la dispersione statistica potrebbe   essere inferiore. Dove unico identificatori sono necessari per distribuire   le applicazioni, in modo che gli UUID non si scontrano anche quando i dati da molti   dispositivi è uniti, la casualità dei semi e generatori usato su   Ogni dispositivo deve essere affidabile per la durata dell'applicazione. Dove   questo non è fattibile, RFC4122 consiglia di utilizzare una variante namespace   invece.

Fonte: Il a caso UUID probabilità di duplicati sezione di questo articolo di Wikipedia su uuid (link porta ad una revisione da dicembre 2016 prima della modifica rielaborato la sezione).

Si veda anche la sezione corrente sullo stesso argomento sullo stesso articolo identificatore univoco universale, collisioni .

Altri suggerimenti

Se per "dato abbastanza tempo" intendi 100 anni e si sta creando loro al ritmo di un miliardo di un secondo, allora sì, si ha una probabilità del 50% di avere una collisione dopo 100 anni.

C'è più di un tipo di UUID, così "come sicuro" dipende da quale tipo (che le specifiche UUID chiamano "versione") che si sta utilizzando.

  • La versione 1 è il tempo basato più l'indirizzo MAC UUID. Il 128-bit contiene 48 bit di indirizzo MAC della scheda di rete (che è assegnato in modo univoco dal costruttore) e un orologio 60 bit con una risoluzione di 100 nanosecondi. Questo orologio avvolge nel 3603 dC così questi UUID sono sicuri, almeno fino a quel momento (a meno che non avete bisogno di più di 10 milioni di nuovi UUID al secondo o qualcuno cloni la scheda di rete). Dico "almeno" perché l'orologio inizia al 15 ottobre 1582, in modo da avere circa 400 anni dopo che l'orologio si avvolge prima che ci sia anche una piccola possibilità di duplicazioni.

  • La versione 4 è il numero UUID casuale. C'è sei bit fissi e il resto del UUID è 122 bit di casualità. Vedere Wikipedia o altra analisi che descrivono il modo molto improbabile un duplicato è.

  • Versione 3 è utilizza MD5 e Versione 5 utilizza SHA-1 per creare quei 122 bit, invece di un generatore di numeri casuali o pseudo-casuale. Quindi, in termini di sicurezza è come la versione 4 di essere un problema di statistica (fino a quando si assicurarsi che ciò che il digest algoritmo è l'elaborazione è sempre unico).

  • La versione 2 è simile alla versione 1, ma con un orologio più piccolo in modo che sta per avvolgere intorno molto prima. Ma dal momento che la versione 2 UUID sono per DCE, non si dovrebbe essere l'utilizzo di questi.

Quindi, per tutti i problemi pratici che sono sicuri. Se vi sentite a disagio con lasciando a probabilità (per esempio il vostro sono il tipo di persona preoccupata per la terra ottenendo distrutta da un asteroide di grandi dimensioni nella vostra vita), basta assicurarsi di utilizzare una versione 1 UUID ed è garantito per essere unico ( nella tua vita, a meno che non si ha intenzione di vivere oltre 3603 dC).

Allora, perché non tutti è sufficiente utilizzare la versione 1 UUID? Questo perché la versione 1 UUID rivelano l'indirizzo MAC della macchina è stato generato su e possono essere prevedibile -. Due cose che potrebbero avere implicazioni di sicurezza per l'applicazione utilizzando quei UUID

La risposta a questa può dipendere in larga misura dalla versione UUID.

Molti generatori UUID utilizzano un numero casuale versione 4. Tuttavia, molti di questi utilizzano Pseudo un generatore di numeri casuali per generare loro.

Se un PRNG mal testa di serie, con un piccolo periodo viene utilizzato per generare l'UUID direi che non è molto sicuro a tutti.

Pertanto, è solo sicuro come gli algoritmi utilizzati per generarla.

Il rovescio della medaglia, se si conosce la risposta a queste domande, allora penso che un uuid versione 4 dovrebbe essere molto sicuro da usare. In realtà sto usando per identificare i blocchi su un file system di rete di blocco e finora non ho avuto uno scontro.

Nel mio caso, il PRNG che sto utilizzando è un tornado Mersenne e sto prestando attenzione al modo in cui è testa di serie, che è da più fonti, tra cui / dev / urandom. twister Mersenne ha un periodo di 2 ^ 19937 -. 1. Sta andando essere un tempo molto lungo prima di vedere una ripetizione uuid

Wikipedia :

  

In questo modo, chiunque può creare un UUID e l'uso   di identificare qualcosa con   ragionevole fiducia che il   identificatore non sarà mai   involontariamente utilizzato da chiunque per   nient'altro

Si va avanti a spiegare in buona dettagli su come sicuro sia in realtà. Quindi, per rispondere alla tua domanda:. Sì, è abbastanza sicuro

regimi UUID utilizzano generalmente non solo un elemento pseudo-casuale, ma anche il tempo di sistema attuale, e una sorta di ID hardware spesso unico se disponibile, ad esempio un indirizzo MAC di rete.

Il punto di usare UUID è che vi fidate a fare un lavoro migliore di fornire un ID univoco di quanto voi stessi sarebbe in grado di fare. Questa è la stessa logica che sta dietro all'uso di un terzo libreria di crittografia partito piuttosto che rotolare il proprio. Fai da te può essere più divertente, ma è in genere meno responsabile di farlo.

ha fatto per anni. Mai incontrato un problema.

Io di solito impostato il mio DB di avere una tabella che contiene tutte le chiavi e le date modificate e così via. Non hanno incontrato un problema di chiavi duplicate di sempre.

L'unico svantaggio che ha è quando si sta scrivendo alcune query per trovare qualche informazione in fretta si sta facendo un sacco di copia e incolla delle chiavi. Non si dispone di breve facile da ricordare più id.

Ecco un frammento di prova per testare è uniquenes. ispirato dal commento di @ scalabl3

  

La cosa divertente è, si potrebbe generare 2 di fila che erano identici, ovviamente a livelli da capogiro di coincidenza, fortuna e l'intervento divino, ma nonostante le probabilità insondabili, è ancora possibile! : D Sì, non accadrà. solo dicendo per il divertimento di pensare a quel momento in cui si è creato un duplicato! il video screenshot! - scalabl3 20 ottobre '15 a 19:11

Se ti senti fortunato, selezionare la casella di controllo, che controlla solo le attualmente generati id. Se si desidera un controllo di storia, lasciare incontrollato. Ti informiamo che potrebbe a corto di RAM ad un certo punto se si lascia deselezionato. Ho cercato di rendere più accogliente della CPU in modo da poter interrompere rapidamente quando necessario, basta premere nuovamente il pulsante di esecuzione frammento o lasciare la pagina.

Math.log2 = Math.log2 || function(n){ return Math.log(n) / Math.log(2); }
  Math.trueRandom = (function() {
  var crypt = window.crypto || window.msCrypto;

  if (crypt && crypt.getRandomValues) {
      // if we have a crypto library, use it
      var random = function(min, max) {
          var rval = 0;
          var range = max - min;
          if (range < 2) {
              return min;
          }

          var bits_needed = Math.ceil(Math.log2(range));
          if (bits_needed > 53) {
            throw new Exception("We cannot generate numbers larger than 53 bits.");
          }
          var bytes_needed = Math.ceil(bits_needed / 8);
          var mask = Math.pow(2, bits_needed) - 1;
          // 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111

          // Create byte array and fill with N random numbers
          var byteArray = new Uint8Array(bytes_needed);
          crypt.getRandomValues(byteArray);

          var p = (bytes_needed - 1) * 8;
          for(var i = 0; i < bytes_needed; i++ ) {
              rval += byteArray[i] * Math.pow(2, p);
              p -= 8;
          }

          // Use & to apply the mask and reduce the number of recursive lookups
          rval = rval & mask;

          if (rval >= range) {
              // Integer out of acceptable range
              return random(min, max);
          }
          // Return an integer that falls within the range
          return min + rval;
      }
      return function() {
          var r = random(0, 1000000000) / 1000000000;
          return r;
      };
  } else {
      // From http://baagoe.com/en/RandomMusings/javascript/
      // Johannes Baagøe <baagoe@baagoe.com>, 2010
      function Mash() {
          var n = 0xefc8249d;

          var mash = function(data) {
              data = data.toString();
              for (var i = 0; i < data.length; i++) {
                  n += data.charCodeAt(i);
                  var h = 0.02519603282416938 * n;
                  n = h >>> 0;
                  h -= n;
                  h *= n;
                  n = h >>> 0;
                  h -= n;
                  n += h * 0x100000000; // 2^32
              }
              return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
          };

          mash.version = 'Mash 0.9';
          return mash;
      }

      // From http://baagoe.com/en/RandomMusings/javascript/
      function Alea() {
          return (function(args) {
              // Johannes Baagøe <baagoe@baagoe.com>, 2010
              var s0 = 0;
              var s1 = 0;
              var s2 = 0;
              var c = 1;

              if (args.length == 0) {
                  args = [+new Date()];
              }
              var mash = Mash();
              s0 = mash(' ');
              s1 = mash(' ');
              s2 = mash(' ');

              for (var i = 0; i < args.length; i++) {
                  s0 -= mash(args[i]);
                  if (s0 < 0) {
                      s0 += 1;
                  }
                  s1 -= mash(args[i]);
                  if (s1 < 0) {
                      s1 += 1;
                  }
                  s2 -= mash(args[i]);
                  if (s2 < 0) {
                      s2 += 1;
                  }
              }
              mash = null;

              var random = function() {
                  var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
                  s0 = s1;
                  s1 = s2;
                  return s2 = t - (c = t | 0);
              };
              random.uint32 = function() {
                  return random() * 0x100000000; // 2^32
              };
              random.fract53 = function() {
                  return random() +
                      (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
              };
              random.version = 'Alea 0.9';
              random.args = args;
              return random;

          }(Array.prototype.slice.call(arguments)));
      };
      return Alea();
  }
}());

Math.guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c)    {
      var r = Math.trueRandom() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
  });
};
function logit(item1, item2) {
    console.log("Do "+item1+" and "+item2+" equal? "+(item1 == item2 ? "OMG! take a screenshot and you'll be epic on the world of cryptography, buy a lottery ticket now!":"No they do not. shame. no fame")+ ", runs: "+window.numberofRuns);
}
numberofRuns = 0;
function test() {
   window.numberofRuns++;
   var x = Math.guid();
   var y = Math.guid();
   var test = x == y || historyTest(x,y);

   logit(x,y);
   return test;

}
historyArr = [];
historyCount = 0;
function historyTest(item1, item2) {
    if(window.luckyDog) {
       return false;
    }
    for(var i = historyCount; i > -1; i--) {
        logit(item1,window.historyArr[i]);
        if(item1 == history[i]) {
            
            return true;
        }
        logit(item2,window.historyArr[i]);
        if(item2 == history[i]) {
            
            return true;
        }

    }
    window.historyArr.push(item1);
    window.historyArr.push(item2);
    window.historyCount+=2;
    return false;
}
luckyDog = false;
document.body.onload = function() {
document.getElementById('runit').onclick  = function() {
window.luckyDog = document.getElementById('lucky').checked;
var val = document.getElementById('input').value
if(val.trim() == '0') {
    var intervaltimer = window.setInterval(function() {
         var test = window.test();
         if(test) {
            window.clearInterval(intervaltimer);
         }
    },0);
}
else {
   var num = parseInt(val);
   if(num > 0) {
        var intervaltimer = window.setInterval(function() {
         var test = window.test();
         num--;
         if(num < 0 || test) {
    
         window.clearInterval(intervaltimer);
         }
    },0);
   }
}
};
};
Please input how often the calulation should run. set to 0 for forever. Check the checkbox if you feel lucky.<BR/>
<input type="text" value="0" id="input"><input type="checkbox" id="lucky"><button id="runit">Run</button><BR/>

Sono d'accordo con le altre risposte. UUID sono abbastanza sicuro per gli scopi pratici quasi tutti 1 , e certamente per il vostro.

Ma supponiamo (ipoteticamente) che non lo sono.

  

Esiste un sistema migliore o uno schema di un certo tipo per alleviare questo problema?

Qui ci sono un paio di approcci

  1. Usa un UUID più grande. Per esempio, invece di un 128 bit casuali, utilizzare 256 o 512 o ... Ogni bit si aggiunge ad un UUID tipo-4 stile ridurrà la probabilità di una collisione con un mezzo, a patto che abbiate una fonte affidabile di entropia < sup> 2 .

  2. Creare un servizio centralizzata o distribuita che genera UUID e registra tutti e ciascuno ha mai emesso. Ogni volta che genera uno nuovo, controlla che l'UUID non è mai stato rilasciato prima. Tale servizio sarebbe tecnicamente straight-forward per implementare (credo) se abbiamo ipotizzato che le persone che gestiscono il servizio erano assolutamente affidabile, incorruttibile, eccetera. Purtroppo, non sono ... soprattutto quando c'è la possibilità dei governi interferenti. Quindi, questo approccio è probabilmente impraticabile, e può essere 3 impossibili nel mondo reale.


1 - Se unicità di UUID verificare se missili nucleari lanciati ricevuti a capitale del suo paese, un sacco di vostri concittadini non sarebbe stato convinto da "la probabilità è molto bassa". Da qui la mia "quasi tutti" qualificazione.

2 - Ed ecco una questione filosofica per voi. C'è qualcosa che non mai veramente casuale? Come potremmo sapere se non fosse? È l'universo come lo conosciamo una simulazione? Esiste un Dio che potrebbe plausibilmente "tweak" le leggi della fisica per alterare un risultato?

3 -. Se qualcuno sa di eventuali documenti di ricerca su questo problema, si prega di commento

Non so se questo è importante per voi, ma tenete a mente che GUID sono globalmente unici, ma sottostringhe di GUID non sono .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top