Sto scrivendo un server applicazioni e ho deciso di utilizzare AES128/CTR/NoPadding per proteggere le connessioni, poiché è considerato abbastanza sicuro senza dover espandere i byte al blocco confine e ho pensato che sia una buona misura per TCP che è logicamente un flusso continuo.Simulazione di un codice di flusso con AES/CTR
Il problema è che Cipher.update() non restituisce il blocco crittografato fino a quando non ha un blocco completo di 16 byte poiché il CTR è fondamentalmente basato su un codice a blocchi tramite simulazione di un codice di flusso. Dovrei leggere i dati da un socket TCP ed elaborare i messaggi non appena arrivano, ma non riesco a recuperare il blocco più recente perché si sta ancora accumulando e la sua dimensione è inferiore a 16 byte. E non posso semplicemente aspettare perché non sappiamo quando verrà inviato il prossimo messaggio. Ovviamente potrei chiamare Cipher.doFinal() per ottenere il rimanente, ma ciò significherebbe la fine del flusso (connessione) e l'oggetto Cipher verrà reinizializzato.
Ho pensato che sarebbe bello se c'è un modo per sbirciare il riporto. CTR semplicemente XORs il testo normale con il keystream quindi dovrei essere in grado di ottenere i dati crittografati indipendentemente dal resto dei byte nel blocco. Ci sarebbe una soluzione alternativa a questo problema? Sto pensando di scrivere un wrapper che crittografa il testo in chiaro con zero per ottenere il keytream in anticipo e gli XOR manualmente, ma mi chiedo come gli altri abbiano risolto questo problema.
Aggiornamento
Sto sviluppando un'applicazione Android e si è scoperto che questo è il problema della Dalvik VM. Come hanno sottolineato Robert e Monnand, Java SE non presenta questo problema almeno con il provider predefinito. Penso che dovrò scrivere una classe wrapper o cambiare la modalità in CFB8 per ovviare a questo problema. (CTR8 non ha funzionato) Grazie per tutte le risposte!
È possibile eseguire il rilievo dei messaggi in modo che la loro lunghezza sia un multiplo di 16? Questo assicurerebbe che tu finisca sempre con un pezzo decifrabile. –
@Chris: Grazie per il suggerimento, potrebbe essere una soluzione possibile. Ma vorrei evitare questo, se possibile, perché non è preferibile in termini di efficienza della rete, anche se potrebbe essere trascurabile. –
Si può semplicemente chiamare questo su un array costituito da zeri per ottenere il keystream. Quindi eseguilo manualmente nel tuo messaggio. – CodesInChaos