Domanda

Sfondo

Io sono la progettazione di un sistema che consente lo sviluppo di schemi di autenticazione dinamici per un utente di contenuti web statici. La motivazione è quella di pre-generare grandi quantità di contenuti web complessi da produrre, ma sensibile, e poi servire in modo statico con autenticazione basata su cookie (embedding informazioni reversably criptato) in luogo, recepita con il web-server inately. Utilizzando una crittografia AEAD modalità primitiva.

Il problema

Ho bisogno di generare IVEC di tasti e che sono validi per un periodo di tempo, diciamo una settimana (la coppia corrente valido). e che IVECs passato / Le chiavi sono valide anche per esempio 2 settimane (storicamente valido) e tutti i dati cifrati con i segreti storicamente valide sarà solo ri-crittografati con la corrente valida IVEC / KEY.

Quello che ho bisogno è un CSPRNG deterministico che i semi di un numero casuale e una password e che può produrre in un modo indicizzato blocchi di 64 bit o 128 bit di numeri. Se uso una settimana-since- "1 gennaio 1970", come uno degli elementi di indice della mia ipotetica CSPRNG dovrei essere in grado di costruire un sistema che cambia in modo innato chiavi automaticamente col passare del tempo.

approccio che sto considerando

Ora non vedo tale funzionalità in cryptopp, o io ora sappiamo la terminologia abbastanza bene, e come cryptopp è il più avanzato delle librerie di crittografia là fuori, non ho fiducia troverò un altro. Quindi, se non riesco a trovare un'implementazione là fuori, avrei dovuto rotolare il mio. Sarà generando una struttura stringa statica di dati concatinated e poi hashing (vedi sotto) fare il trucco?

RIPEMD160 (RandomPreGeneratedFixedNonce: passphrase: UInt64SinceEpoch: 128BitBlockIndexNumber);

Nota: Le blocknumbers saranno assegnati e hanno una struttura regolare, così per esempio per un 128 bit digest, i primi 64 bit del blocco 0 saranno per l'Ivec, e tutti 1 come 128 bit chiave.

E 'questo un approccio suono (-. Cioè, crittograficamente sicuro)?

- edit: dopo accettare il commento -

Dopo qualche riflessione, ho deciso di unire quello che originariamente considerato la passphrase e la nonce / sale in una chiave di 16 byte (cryptographicall forte), e utilizzare le tecniche descritte nel PKCS # 5 di base time-Derive multipla chiavi. Non c'è bisogno di un sale, come passphrase non vengono utilizzati.

È stato utile?

Soluzione

Domanda interessante.

In primo luogo, i vettori iniziali non c'è bisogno di essere crittograficamente forti quantità casuali, ma dovrebbe sia per-messaggio unico. La IV è in realtà solo una sorta di valore sale che garantisce che i messaggi simili crittografati utilizzando la stessa chiave non lo fanno aspetto simile una volta che sono criptati. È possibile utilizzare qualsiasi generatore pratica pseudo-casuale per generare il IV, e quindi inviarlo (preferibilmente criptato) insieme con i dati crittografati.

I tasti, ovviamente, deve essere forte come si può praticamente fare loro.

La tua proposta di hash una stringa di testo che contiene un nonce, passphrase, e dati di validità mi sembra essere molto ragionevole - è sostanzialmente in linea con quanto fatto da altri sistemi che utilizzano una passphrase per generare una chiave. Si dovrebbe hash più volte - non solo una volta - per rendere la generazione delle chiavi computazionalmente costoso (che sarà un problema più grande per chiunque cerchi di forza bruta la chiave di quello che sarà per voi)

.

Si potrebbe anche voler dare un'occhiata al sistema di generazione delle chiavi di cui PKCS # 5 (ad esempio a http://www.faqs.org/rfcs/rfc2898.html ) che è implementato in cryptopp come PasswordBasedKeyDerivationFunction. Questo meccanismo è già ampiamente utilizzato e conosciuto per essere ragionevole sicuro (si noti che PKCS # 5 raccomanda l'hashing dei dati passphrase almeno 1000 volte). Si può solo aggiungere il vostro periodo di validità ei dati indice per la passphrase e l'uso PasswordBasedKeyDerivationFunction così com'è.

Non c'è dire ciò algoritmo di crittografia che si propone di utilizzare per crittografare i dati, ma vorrei suggerire che si dovrebbe scegliere qualcosa di diffuso e conosciuto per essere sicuro ... e, in particolare, mi piacerebbe suggerire che si utilizza AES. Vorrei anche suggerire utilizzando uno dei SHA funzioni digerire (forse come input per PasswordBasedKeyDerivationFunction). SHA-2 è attuale, ma SHA-1 è sufficiente per scopi principali generazione.

È anche non dire quello che la lunghezza della chiave che stai cercando di generare, ma si deve essere consapevoli che la quantità di entropia nelle vostre chiavi dipende dalla lunghezza della passphrase che si utilizza, e meno che la passphrase è molto a lungo che sarà molto inferiore al keylength richiede idealmente.

L'anello più debole in questo schema è la passphrase in sé, e che sta andando sempre di limitare il livello di sicurezza è possibile achive. Finché ti sale dei dati (come si sta facendo) e rendere la chiave di generazione costoso per rallentare gli attacchi di forza bruta si dovrebbe andare bene.

Altri suggerimenti

  

Quello che ho bisogno è un CSPRNG deterministico che i semi di un numero casuale e una password e che può produrre in un modo indicizzato blocchi di 64 bit o 128 bit di numeri. Se uso una settimana-since- "Jan 1 1970", come uno degli elementi di indice della mia ipotetica CSPRNG dovrei essere in grado di costruire un sistema che cambia in modo innato chiavi automaticamente col passare del tempo.

Bene, io pensare parte della soluzione è quella di utilizzare un generatore a base non-tempo. In questo modo, se entrambe le parti iniziano con lo stesso seme, poi entrambi producono lo stesso flusso casuale. È possibile sovrapporre i tuoi "settimane da Settimana 1, 1970" logica in cima a quello.

Per fare questo, è necessario utilizzare OFB_mode<T>::Encryption. Può essere utilizzato come generatore perché utilizza la modalità OFB AdditiveCipherTemplate<T>, che deriva da RandomNumberGenerator.

In realtà, Crpyto ++ utilizza il generatore in test.cpp in modo che i risultati possono essere riprodotti se qualcosa non funziona. Ecco come si usa OFB_mode<T>::Encryption. Si applica anche ai CTR_Mode<T>::Encryption:

SecByteBlock seed(32 + 16);
OS_GenerateRandomBlock(false, seed, seed.size());

for(unsigned int i = 0; i < 10; i++)
{
    OFB_Mode<AES>::Encryption prng;
    prng.SetKeyWithIV(seed, 32, seed + 32, 16);

    SecByteBlock t(16);
    prng.GenerateBlock(t, t.size());

    string s;
    HexEncoder hex(new StringSink(s));

    hex.Put(t, t.size());
    hex.MessageEnd();

    cout << "Random: " << s << endl;
}

La chiamata alla recupera OS_GenerateRandomBlock byte dal /dev/{u|s}random e quindi utilizza che come un seme condiviso simulato. Ogni esecuzione del programma sarà diverso. All'interno di ogni esecuzione del programma, stampa simile al seguente:

$ ./cryptopp-test.exe
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD

C'è un altro generatore a disposizione che fa lo stesso, ma la sua non parte della libreria Crypto ++. La sua chiamata AES_RNG, e la sua base di AES-256. Il suo colpo di testa unica implementazione, e si può trovare presso il Crypto ++ wiki sotto RandomNumberGenerator .

Si veda anche l'argomento riproducibilità per la classe RandomNumberGenerator sul Crypto ++ wiki.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top