Vorrei utilizzare un archivio di valori-chiave (cassandra, redis, ...), ma non mi fido del server.
I client hanno un segreto condiviso e lo sto usando per crittografare i valori memorizzati. Ma qual è il modo corretto di crittografare le chiavi (non le chiavi di crittografia, le chiavi del negozio di chiavi-valore)?
-
L'archivio confronta le chiavi nelle query, quindi ogni chiave in chiaro deve avere solo una chiave crittografata corrispondente.
-
Ovviamente, se un utente malintenzionato ottiene la chiave crittografata, deve essere altrettanto semplice scoprire la chiave in chiaro.
-
Meno ovviamente, se un utente malintenzionato può indovinare la chiave in chiaro, deve essere impossibile ottenere la chiave crittografata senza il segreto. Non voglio che un utente malintenzionato sia in grado di confermare se una determinata chiave è presente nell'archivio valori-chiave.
-
Le collisioni (diverse chiavi in chiaro con uguale chiave crittografata) dovrebbero essere così rare che non possono essere create di proposito da un utente malintenzionato.
La crittografia simmetrica con i vettori di inizializzazione casuale o l'hashing con i sali è proibita da (1). Un hash della chiave in chiaro senza sale non soddisfa (3).
Vedo due opzioni:
-
crittografare con un IV statico.
-
hash(secret || plaintext-key)
Il primo sembra molto simile all'improvvisazione di una funzione di hash con un codice. Permetterebbe anche la decrittazione, di cui non ho bisogno. Modifica: poiché IV non è casuale, le chiavi in chiaro con prefisso uguale avranno lo stesso prefisso nel testo cifrato, con possibilità di ragionare sul testo in chiaro.
Il secondo memorizza il segreto di hash, ma senza le solite precauzioni, come la salatura e lo stiramento delle chiavi. Modifica: è anche vulnerabile a Length_extension_attacks .