Ho scritto una classe che crittografa e decodifica con cifrari a blocchi. Voglio usare la Counter Mode (CTR / CM). Sappiamo che Counter Mode genera un keytream basato sui contatori, quindi XOR il keystream con testo in chiaro per produrre testo cifrato. Quindi, è possibile decifrare finché è in grado di riprodurre il keystream, cioè, riprodurre il contatore e ottenere la chiave giusta.
Ho osservato che il metodo decrypt di un cifrario non è necessario in modalità CTR, dal momento che per riprodurre il keystream abbiamo solo bisogno di crittografare nuovamente i blocchi contatore.
Quindi, perché non posso sostituire il cifrario ordinario con una funzione hash (quindi rendere la parte fondamentale del contatore) o una funzione HMAC (che accetta una chiave)? Le funzioni hash non sono così pseudocasuali se confrontate con le cifre nella generazione di keystream, o c'è un motivo in più?
p.s .: Questa domanda funziona anche con la modalità OFB - l'hashing di una IV con o senza un tasto genera ancora qualcosa che assomiglia a un keystream.
p.s.2: un esempio:
1) Costruiamo un contatore di 16 byte:
aPADDING00000000
aPADDING00000001
aPADDING00000002
Qui otteniamo 3 blocchi.
2) Quindi utilizzare HMAC di MD5 per generare il keystream:
key = 'This is a key.'
stream[0] = HMAC('This is a key.','aPADDING00000000').hexdigest()
stream[1] = HMAC('This is a key.','aPADDING00000001').hexdigest()
stream[2] = HMAC('This is a key.','aPADDING00000002').hexdigest()
# now stream is:
# ['73f2e665c30aaec5bbead51166aaa85f',
# '91392d0755638fbce5c689f96b02494f',
# '1d18a81751179858d151dd86179385f9']
stream_str = "".join(stream).decode('hex') # stream_str = '73f2 ... 85f9'.decode('hex')
3) Ora stream_str sembra molto simile a un keytream. Per crittografare:
plaintext = 'This is a plaintext that has length of 48 bytes.'
ciphertext = stream_xor(plaintext,stream_str) # stream_xor XORs the two inputs bit by bit.
o, per decifrare:
decrypted = stream_xor(ciphertext,stream_str) # ciphertext produced before.