Domanda:
Esiste un modo per accettare le richieste firmate senza memorizzare la password del client in testo normale?
galymzhan
2011-03-11 17:01:37 UTC
view on stackexchange narkive permalink

Stiamo sviluppando il servizio Web REST. Forniremo identificatore e stringa segreta a ciascuno dei nostri client REST. Quando eseguono le richieste, i client si autenticheranno utilizzando l ' algoritmo HMAC (firmeranno il corpo e le intestazioni delle richieste HTTP utilizzando la stringa segreta). Il servizio REST riceverà le intestazioni HTTP, il corpo, trova il segreto del client dal database utilizzando il suo identificatore, lo firma e verifica se la firma calcolata è uguale alla firma fornita dal client.

In realtà, è meglio spiegato in Pagina di documentazione sull'autenticazione Amazon S3.

Per utilizzare questo schema dobbiamo memorizzare le chiavi segrete dei clienti in testo normale, giusto?

C'è un altro modo per autenticare i client senza memorizzare le loro chiavi segrete sui nostri server (o archiviarle in modo non recuperabile, ad esempio i loro hash MD5)?

Tre risposte:
Thomas Pornin
2011-03-11 20:00:11 UTC
view on stackexchange narkive permalink

A rigor di termini, l'uso del termine "firma" su HMAC è improprio; è molto diffuso, ma ancora errato: le firme riguardano algoritmi asimmetrici con una chiave pubblica e una privata, come RSA.

HMAC utilizza una chiave segreta (cioè un mucchio di byte arbitrari) che viene utilizzata per l'elaborazione il MAC e per verificarlo (viene effettivamente verificato ricalcolandolo). Quindi, nel tuo problema, sì, il server deve memorizzare o la chiave segreta o alcuni dati sufficienti per recuperarla.

Nota che la chiave segreta K può essere derivato da la password in modo non invertibile. Per esempio. tramite una funzione hash o, meglio ancora, con una Key Derivation Function. Il server memorizzerà la chiave K "in chiaro" e conoscere la chiave K è sufficiente per produrre valori HMAC validi. Tuttavia, questo costringe un utente malintenzionato a utilizzare un software specifico per questo, non il client standard che richiede una password utente. A seconda del contesto e del modello di attacco, questo può o non può essere un miglioramento della sicurezza.

Un modo per ottenere ciò che stai cercando, ma con una complessità maggiore di un semplice HMAC, è usare SRP. SRP è un protocollo di scambio di chiavi asimmetriche con autenticazione reciproca basata su password, con le seguenti caratteristiche:

  • Non è necessaria la distribuzione di chiavi pubbliche (PKI, certificati ...).
  • Il client autentica il server e il server autentica il client, nello stesso passaggio, anche in presenza di aggressori attivi (gli aggressori "Man-In-The-Middle" vengono sconfitti).
  • Nessun aggressore attivo o passivo apprende informazioni sufficienti per eseguire attacchi con dizionario offline (un attacco con dizionario è indovinare la password provando parole casuali; l'attacco è offline se può essere fatto senza interagire con il client o il server onesto per ogni ipotesi).
  • Ciò che il server memorizza non è sufficiente per apprendere la password o impersonare il client (ma consente attacchi al dizionario offline, il che è inevitabile).

La chiave che risulta dal protocollo SRP può quindi essere utilizzata per un algoritmo MAC come HMAC. Non ha bisogno di essere memorizzato: viene semplicemente mantenuto nella RAM per la durata della sessione.

SRP può essere integrato in TLS, come spiegato in RFC 5054. Il modo più semplice e standard supportato per utilizzare SRP nel proprio contesto sarebbe utilizzare HTTPS (ovvero HTTP all'interno di un tunnel SSL / TLS) con la parte TLS utilizzando SRP per lo scambio di chiavi. GnuTLS è un'implementazione opensource di SSL / TLS che supporta SRP.

Sembra che non ci siano così tante implementazioni di librerie client / server disponibili (ho trovato mod_gnutls per apache) per SRP. Ce ne sono alcuni? Inoltre, devo acquistare un certificato SSL, SRP afferma di non aver bisogno di terze parti affidabili?
Non hai mai bisogno di _acquistare_ un certificato; un certificato è "solo" un BLOB firmato da un'autorità di certificazione. Ciò di cui hai bisogno è un certificato che sarà accettato dal peer e il peer accetta i certificati in base a ciò che CA li ha prodotti. Se controlli sia client che server, puoi usare la tua CA, che non ti costerà nulla (vedi http://www.ejbca.org/ o http://www.openssl.org/ per i dettagli). Inoltre, con SRP, non è necessario alcun certificato, acquistato o meno.
Tom Wu
2011-03-13 06:55:50 UTC
view on stackexchange narkive permalink

SRP non richiede una terza parte attendibile o un certificato SSL perché utilizza il segreto condiviso esistente tra client e server per l'autenticazione. Una terza parte non è necessaria quando le due parti originali si fidano già l'una dell'altra. E a differenza degli schemi basati su HMAC, SRP memorizza la password sul server in un modo "non recuperabile" o non equivalente al testo in chiaro, il che significa che un utente malintenzionato che apprende il segreto del server non ottiene la capacità di impersonare un client.

Altri vantaggi di TLS-SRP rispetto a uno schema HMAC ad-hoc sono: resistenza agli attacchi del dizionario offline, resistenza agli attacchi di riproduzione e crittografia del trasporto.

L'unico svantaggio di SRP è la mancanza di implementazioni client / server pronte per la produzione distribuite come librerie. Ho ragione?
Tom Wu
2011-03-16 02:25:50 UTC
view on stackexchange narkive permalink

Come ha sottolineato Thomas Pornin, SRP / TLS è supportato in GnuTLS e OpenSSL supporterà le suite di cifratura SRP nella versione 1.0.1. Le patch sono disponibili per OpenSSL 0.9.8 e 1.0.0. Se la tua applicazione utilizza C / C ++, sei abbastanza ben coperto.

Per Java, c'è BouncyCastle, e per Python, c'è TLSLite. Quale lingua e piattaforma stai utilizzando?

Ho ragione a presumere che tu sia il Tom Wu che ha inventato SRP? Benvenuto!! E immagino che l'altro intervistato di Tom Wu stia rispondendo per primo come utente non registrato? Ben ironico :)
http://trevp.net/tls_srp/index.html dice che TLSLite implementa una vecchia bozza di RFC5054 per SRP ma non chiarisce di più. Quali sono le differenze?
Giusto su entrambi i fronti. Per quanto riguarda TLSLite, l'unica differenza dovrebbe essere il calcolo di "k", uno dei valori intermedi. Una bozza precedente lo aveva fissato a 3, ma RFC5054 lo rende un hash dei parametri N e g.
Il mio servizio REST è scritto in PHP (LAMP classico), ho trovato `mod_gnutls` per Apache, ma memorizza i dati SRP nei file, non nel database, sebbene non sia un grosso svantaggio. Esistono client per PHP e ActionScript di Flash?


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 2.0 con cui è distribuito.
Loading...