Sistema per l'autenticazione sicura dell'acquisizione di contenuto

3

Ho problemi a progettare un sistema per contenuti autenticati dal mio sito distribuiti da altre persone. Sto lavorando su Ruby on Rails, ma non penso che a livello teorico la mia domanda non sia ristretta a quel framework. Per non dare troppo spazio, il mio sito (chiamiamolo www.site.com) aiuta le aziende a tenere l'inventario di chi ha acquistato l'articolo e consente ai clienti di visualizzare la cronologia degli acquisti.

Quindi, ho il seguente problema:

  1. Supponiamo che Alice venda cheeseburger. Alice fa un account su site.com e registra i suoi cheeseburger come un oggetto che vende. Di conseguenza, site.com memorizza il cheeseburger di Alice in un database SQL con l'ID 92314
  2. Bob è un cliente dello stand del cheeseburger di Alice e ha recentemente acquistato un cheeseburger.
  3. Alice vorrebbe dire a Bob di site.com e della sua capacità di monitorare gli acquisti. Quindi, Alice invia una richiesta a site.com per restituire hashA corrispondente all'elemento con ID 92314.
  4. Bob visita www.site.com/purchase/hashA e viene richiesto di creare un account o di accedere per registrare il suo nuovo acquisto di cheeseburger da Cheeseburger deliziosi e deliziosi di Alice.
  5. Charlie visita anche lo stand del cheeseburger di Alice e acquista un cheeseburger.
  6. Alice vorrebbe anche dire a Charlie di site.com e invia una richiesta che genera hashB per Charlie da utilizzare nello stesso modo.

La mia domanda è, come faccio a trovare uno schema che può generare hashA e hashB in modo che il mio server web possa cercare in modo efficiente gli articoli. Sospetto che hashB possa essere generato da hashA utilizzando un codice di ordinamento che utilizza hashA come seme. Non so come, dopo aver ricevuto hashA o hashB , site.com saprà che corrisponde all'articolo 92314. Sospetto che usando un nonce ti aiuterà.

Le cose che vorrei evitare includono:

  • Avere Charlie usa hashA dopo che è stato usato da Bob
  • Esposizione dell'id 92314 all'utente
  • Avere un singolo punto di errore (vale a dire una singola chiave che crittografa gli hash per tutti gli ID)
  • Le cose si interrompono se Charlie usa hashB prima che Bob usi hashA .

Dichiarazione di non responsabilità: la mia esperienza è più legata alla computer grafica e meno allo sviluppo web o alla crittografia, quindi indirizzarmi verso Google è utile. Se questo appartiene a uno degli altri siti di stackexchange (Cryptography, Programmers, ecc.). Sentiti libero di farmelo sapere e lo sposterò.

    
posta Mokosha 29.09.2013 - 19:58
fonte

2 risposte

4

Se comprendo correttamente il problema:

  • Alice è autenticato con il server. Quando Alice parla al server, il server sa che si tratta di Alice.
  • Alice ha un "elemento" sul server corrispondente a qualche ID nel database.
  • Alice può concedere una sorta di accesso all'oggetto, a persone di sua scelta, ad es. Bob e Charlie.
  • Bob e Charlie si connetteranno al server in seguito , utilizzando un token che è stato loro inviato da Alice e che rappresenta l'accesso direttamente sul server.
  • L'ID non deve essere rivelato a nessuno al di fuori del server. I token per Bob e Charlie devono essere distinti l'uno dall'altro e non essere ipotizzabili.

Quindi questo punta a questa soluzione generica:

  • Quando Alice ottiene un nuovo token T dal server, il server ricorda che "il valore del token T è per l'articolo 92314". Questa memoria è, per esempio, una nuova riga in una tabella di database dedicata.
  • Ogni volta che Alice richiede un nuovo token T , il server ne genera uno a caso. Se i valori del token sono sufficientemente grandi (16 byte o più), la probabilità che il server generi il doppio dello stesso valore di token è trascurabile. In alternativa, poiché il server memorizza tutti i token prodotti, può forzare l'unicità.
  • Opzionalmente , il token T può essere limitato nel tempo (il Server dimentica i token emessi dopo un po 'di tempo) e / o un colpo (il Server dimentica i token emessi dopo l'uso).
  • Opzionalmente , quando Alice ottiene un token T , può dire al server "questo è per Bob" in modo che quando Bob si connette, parti del modulo di registrazione sono già compilate.

Con un limite di tempo, il numero di token da ricordare, con la loro associazione all'ID oggetto e alle informazioni utente facoltative, può rimanere limitato e quindi essere tecnologicamente gestibile.

Un'ottimizzazione è di scaricare questa memoria su Bob. Ciò significa che il server codificherà nel valore del token stesso qualunque cosa avrebbe voluto ricordare. In questo senso, la memoria è gratuita. Tuttavia, questo richiede la crittografia, perché:

  • Non dovrebbe essere possibile per gli estranei generare valori di token che il server accetterà; generazione di token dovrebbe essere un monopolio server. Ciò indica la necessità di un MAC .

  • I contenuti del token, che il server vuole ricordare, sono riservati. Quindi è necessaria anche la crittografia.

In entrambi i casi, ci sono delle chiavi, ed è inevitabile: i tasti sono conoscenza, e in crittografia la conoscenza è potere. Tutti possono acquistare gli stessi computer, quindi se il Server può generare valori di token e altre persone non possono, allora il Server deve sapere qualcosa che le altre persone non sanno. Quel "qualcosa" è ciò che i crittografi chiamano una chiave. La crittografia può aiutarti a concentrare quella "conoscenza" in un valore molto piccolo e non mutante, ad esempio una sequenza di 128 bit (16 byte). Ma non può farlo scomparire del tutto.

Lo schema per questo server "senza memoria" è quindi:

  • Dati dati D , il valore del token T è la crittografia + MAC di D . Per creare token per Bob e Charlie distinti, D può contenere un contatore globale, la data di produzione e / o alcuni byte casuali. D conterrà anche l'ID dell'articolo e tutto ciò che il Server vuole "ricordare" su questo token.

  • Quando si riceve un token T , il server controlla il MAC e lo decrittografa, ottenendo D , quindi tutto ciò che è necessario per registrare Bob (o Charlie) .

  • Opzionalmente , quando viene creato l'account di Bob, il valore del token T usato da Bob viene registrato nell'account di Bob. Pertanto, quando viene ricevuto un token T ', il server può verificare se T' non è già stato utilizzato per creare un account. Questo per impedire a Bob stesso di dare copie del suo gettone ai suoi amici. Questo implementa una proprietà "one-shot" per il token.

Combinare correttamente crittografia e MAC è una questione di sottigliezza . Se si esegue questa strada, si consiglia di utilizzare una modalità di crittografia che esegue sia la crittografia che il MAC in modo crittograficamente corretto; cioè GCM o EAX .

    
risposta data 29.09.2013 - 20:49
fonte
5

Whoa! Stai complicando eccessivamente il problema; la questione è molto più semplice.

Tabella 1 ( products )

product_id - product_name - product_key

product_key può essere semplicemente il sha1() di product_id , product_name e alcuni byte casuali. Oppure, meglio, prendi solo 16 byte casuali e passali a sha1() .

Tabella 2 ( requests / invitations )

request_id - product_id - request_key - valid

request_key è generato allo stesso modo: il prodotto sha1() di request_id , product_id e alcuni byte casuali. O, semplicemente, il sha1() di circa 16 byte casuali.

Ora, quando Alice vuole dire a Bob circa site.com , verrà generata una riga in "Tabella 2" e lei gli invierà semplicemente il link site.com/purchase/request_key .

La stessa cosa accade quando si dice a Charlie; verrà generata una nuova riga in "Tabella 2" (nuovo request_key ), quindi un nuovo collegamento. Una volta che il link è visitato, controlli se valid è true . Quando si utilizza la chiave, si imposta valid su false .

  • La chiave può essere utilizzata solo una volta.
  • L'ID non è esposto.
  • Nessuna crittografia di fantasia.
  • Ogni chiave di richiesta è indipendente.
risposta data 29.09.2013 - 20:41
fonte