Utilizzo di HMAC per generare chiavi segrete

10

Sto sviluppando una piattaforma che utilizza diverse chiavi segrete per diversi usi: key1 per password di hashing (usando pbkdf2-hmac-sha256), key2 per generare non ripetibili uuids imprevedibili (usando aes-128 e un contatore), ecc.

Invece di memorizzare chiavi diverse, ho pensato di generarle da una singola chiave, cioè:

key1 = HMAC(primary_key, "key1");
key2 = HMAC(primary_key, "key2");
...

C'è qualche difetto critico nel farlo? Questo schema di programmazione è comune? Generare le chiavi separatamente offre ovviamente un piccolo vantaggio che non ci sono dipendenze matematiche tra le chiavi. Tuttavia, da quello che capisco anche se un utente malintenzionato trova key1 non sarà in grado di trovare primary_key o key2 , giusto?

Grazie

    
posta Oren 14.01.2015 - 17:29
fonte

1 risposta

1

Risposta breve: hai ragione e puoi farlo.

Tuttavia, per sicurezza, è necessario assicurarsi di non abbassare la sicurezza della funzione HMAC usandola correttamente e non mettendo aspettative errate sulla funzione utilizzata.

In base alla progettazione, le funzioni HMAC prevedono che un parametro sia una chiave segreta e l'altro sia un messaggio che potrebbe essere pubblico (puoi trovare ulteriori informazioni qui e ). Ciò significa che gli argomenti non sono liberamente intercambiabili, l'ordine esatto dipende dalla lingua utilizzata.

Una chiave segreta è una chiave:

  • che è composto da caratteri casuali scelti dal computer,
  • La cui lunghezza minima è la lunghezza dell'hash risultante,
  • Che non è mai conosciuto dall'utente remoto, nemmeno una parte di esso,
  • Che non può essere controllato o influenzato in alcun modo dall'utente remoto.

A seconda della tua effettiva necessità e implementazione, tutti i parametri che fornirai alla funzione HMAC potrebbero non essere utilizzabili come chiave segreta:

  • primary_key potrebbe essere un servizio o un nome di dominio per il quale dovrai derivare più chiavi, nel qual caso potrebbe essere una stringa pubblica accessibile all'utente finale,
  • keyn (key1, key2, ecc.) può anche essere una stringa prevedibile corrispondente, ad esempio, al servizio interno per cui la chiave deve essere generata.

Applicato alla tua domanda, abbiamo quindi le seguenti possibilità:

  • Nessuno dei parametri può essere considerato una chiave veramente sicura, ma una di esse è una password o equivalente : se la tua primary_key è una password fornita dall'utente (cioè una stringa casuale generata da un essere umano), puoi rimanere sicuro utilizzando una funzione di hash dedicata alla password . Tale primary_key potrebbe essere vulnerabile agli attacchi di dizionario e amp; co., ma questa minaccia sarà mitigata dall'uso di una funzione di hash corretta a spese delle prestazioni dell'applicazione (tali funzioni di hash sono progettate per essere lente).
  • Nessuno dei parametri può essere considerato una chiave veramente sicura e non include nemmeno una password : un esempio di tale situazione sarebbe se primary_key riflette o viene dedotto dal nome di dominio fornito dall'utente e keyn contiene il nome del servizio o del server (o è dedotto da tali informazioni) per cui verrà generata la chiave finale. Quindi considera il tuo sistema come difettoso, fine della storia. Il tuo sistema è sbagliato e non sicuro.
  • Uno di questi parametri può essere considerato come una chiave sicura : fai attenzione a passare questo parametro attraverso l'argomento appropriato dove la chiave segreta è prevista dalla funzione HMAC. Non farlo potrebbe compromettere la forza crittografica della funzione HMAC. Ad esempio, supponiamo che primary_key sia un nome di dominio o servizio, mentre keyn è una chiave sicura, rispetto alla tua domanda potresti dover ripristinare i tuoi argomenti: key1 = HMAC("secret_key_1", primary_key); , fare riferimento alla documentazione della tua lingua in caso di dubbio ,
  • Entrambi questi parametri possono essere considerati come chiavi di sicurezza : quindi hai la massima sicurezza che puoi aspettarti da questo schema, gli argomenti possono essere passati in qualsiasi ordine senza aumentare o diminuire la sicurezza (le chiavi risultanti essere ovviamente diverso ma con le stesse proprietà di sicurezza).

Come nota a margine, HMAC RFC menziona anche la possibilità di troncare l'hash risultante per ridurre le informazioni disponibili a un attacker che proverebbe a dedurre primary_key a partire da un hash. La stessa RFC ammette tuttavia che mentre alcune ricerche " mostrano alcuni vantaggi analitici del troncamento dell'output delle funzioni MAC basate su hash ", " i risultati in quest'area non sono assoluti " . Per quanto le tue chiavi iniziali siano sicure, ho la sensazione personale che tu possa avere di più da perdere in tale troncamento a causa delle chiavi risultanti più brevi. In ogni caso, questa RFC consiglia di mantenere la parte più a sinistra dell'hash risultante e di conservarne almeno la metà.

    
risposta data 28.07.2015 - 12:01
fonte

Leggi altre domande sui tag