Come esercizio, sto scrivendo un codice che accetta un elenco di proprietà possibilmente segrete (ad es. ID utente, password, indirizzo IP), aggiunge un timestamp, lo crittografa e lo firma.
Ecco una panoramica di alto livello su cosa fa il codice - sembra corretto dal punto di vista che dovrebbe garantire la segretezza e l'integrità?
La cosa principale di cui sono incerto è derivare la chiave di crittografia e la chiave di firma dalla stessa chiave segreta fornita dall'utente, ma questo sembra un po 'paranoico dato che non dovrebbe esserci alcuna relazione tra i due assumendo la forza del sottostante funzione di hash dell'algoritmo di derivazione della chiave.
Se qualcuno è interessato, il codice sorgente insieme a una piccola suite di test, impacchettata con setuptools, può essere trovata qui .
Attuazione
L'utente fornisce una chiave privata e due sali opzionali che utilizziamo per derivare la crittografia e le chiavi di firma usando PBKDF2. Se non viene fornito alcun sale, due vengono generati usando urandom
.
Successivamente, l'utente fornisce un elenco di stringhe di proprietà, ['a', 'b', 'c',...]
che viene convertito in una stringa | -delimitata e a cui viene anteposto str(time.time())
. Questo testo in chiaro è riempito con il metodo PKCS # 7. Un vettore di inizializzazione (IV) viene generato utilizzando urandom
e il testo in chiaro viene quindi crittografato con AES-256 (modalità CBC) utilizzando la chiave sopra descritta e la IV.
Il testo cifrato IV + viene quindi firmato utilizzando l'implementazione nativa di HMAC-MD5 di Python con la chiave di firma derivata come descritto sopra e questa firma viene aggiunta al messaggio.
Il processo di decrittografia e verifica segue approssimativamente il processo inverso come sopra, con un'attenzione particolare nel passaggio di verifica per utilizzare il metodo compare_hash
incorporato per prevenire la vulnerabilità a causa dell'attacco temporale.