Entra

View Full Version : [JAVA] Salvare in file tramite "Serializzazione"


Speed_89
11-02-2010, 20:47
Salve a tutti, ho in mente di creare un programma in Java per archiviare le mie password. Pensavo di salvare il tutto in un file di testo da poi magari crittografare, al che mi è venuto il dubbio su dove conservare la chiave... Quindi ho pensato un'altra cosa...
Siccome intendevo creare due classi, una che incapsulasse tutte le info riguardo una password, e un'altra che incapsulasse l'elenco di password e le info ad esso inerenti, potrei implementare l'interfaccia Serializable in queste classi e salvare tutti gli oggetti su file mediante serializzazione...

La mia domanda è... Le info sugli oggetti saranno codificate in bytecode in un file... Può qualcuno essere in grado di estrapolare da questo byte code le info contenute negli oggetti? In parole povere le password...

fero86
11-02-2010, 21:25
si. e comunque non mi affiderei lo stesso alla security by obscurity.

il dilemma di dove mettere la chiave crittografica chiaramente non ha soluzione, la soluzione é semplicemente quella di non metterla sullo stesso PC, o anche su nessun PC.

solo la tecnologia del Trusted Computing ti permetterebbe di conservare la chiave sul PC in maniera sicura, ma non la puoi usare tanto facilmente da Java (dovresti usare JNI).

fero86
11-02-2010, 21:41
un consiglio per ridurre le dimensioni della chiave: come schema crittografico usa lo XOR contro una serie di numeri pseudocasuali sicuri generati da un certo seed; il seed é la chiave, puoi usarne uno da 64 bit (un long).
c'é sempre vantaggio nel ridurre le dimensioni della chiave perché piu é grossa e meno passa inosservata.

come PRG sicuro puoi usare SHA1PRNG, di cui trovi un'implementazione in questa classe Java: http://java.sun.com/javase/6/docs/api/index.html?java/security/SecureRandom.html

non riusare mai la stessa chiave altrimenti lo XOR diventa vulnerabile: due cose diverse devono essere crittografate con le sequenze pseudorandom generate da due seed diversi.

con questo sistema hai le seguenti garanzie:
- si ipotizza che nessuna macchina di Turing polinomiale* sia in grado di prevedere correttamente con probabilitá non trascurabile una sequenza SHA1PRNG senza conoscere il seed;
- la distribuzione dei ciphertexts prodotti dallo XOR é indipendente dalla distribuzione dei plaintexts, quindi la frequenza di un certo ciphertext non dice nulla su quale potrebbe essere il corrispondente plaintext. lo XOR é un cosiddetto schema "perfettamente segreto", molto piu robusto di tutti gli altri; non lo si usa solo perché é scomodo (la chiave deve essere grossa esattamente quanto il plaintext e non sempre si puó fare affidamento su un PRG, inoltre deve essere usa e getta, non bisogna mai usare due volte la stessa chiave).

quindi hai un buon livello di sicurezza.

*una macchina di Turing polinomiale é una macchina di Turing i cui tempi di elaborazione si sanno essere ragionevoli solo se sono asintoticamente polinomiali rispetto alla dimensione del problema. i nostri computers sono assimilabili a macchine di Turing polinomiali perché per eseguire algoritmi esponenziali potrebbero impiegare anche anni; i computers quantistici invece non lo sono perché eseguono algoritmi esponenziali in tempo lineare, peró ancora non esistono.

Speed_89
11-02-2010, 22:45
Salve fero86, ti ringrazio per le risposte, purtroppo mi rincresce dirti che non ho capito molto... :stordita:

Ho capito che il metodo della serializzazione degli oggetti non è affidabile per mettere al sicuro i dati. E su questo ok.

Poi per quanto riguarda la questione di dove mettere la chiave, io mi riferivo alla situazione nella quale uso un semplice cifrario, tipo a trasposizione o di giulio cesare, nel quale l'utente del programma sceglie una chiave, e poi il programma quando dovrà decifrare, sarà costretto a confrontare la chiave immessa con quella in precedenza scelta, quindi dovrà conservarla nel file...

So che queste cose ormai sono superate, però io purtroppo ne so veramente poco di crittografia... Non so, mi potresti indirizzare verso qualche metodo o classe java che mi aiuterebbe ad iniziare, qualcosa di semplice, nn per forza un metodo inattaccabile... Grazie ancora! :)

banryu79
12-02-2010, 09:08
il dilemma di dove mettere la chiave crittografica chiaramente non ha soluzione, la soluzione é semplicemente quella di non metterla sullo stesso PC, o anche su nessun PC.

Se è per suo uso personale, e lo scopo è fare il backup delle password potrebbe essere sufficiente conservare la chiave crittografica su una chiavetta usb?

Speed_89
12-02-2010, 13:32
Se è per suo uso personale, e lo scopo è fare il backup delle password potrebbe essere sufficiente conservare la chiave crittografica su una chiavetta usb?

Non è per uso personale, volevo effettivamente sviluppare questa piccola utility... La questione della password me la ponevo perchè non avendo pensato di usare chi sa che algoritmo, ma un semplice cifrario, c'era il problema che il programma doveva conservare nel file anche la chiave del cifrario...

Per come avete inteso voi la questione della password, la soluzione megliore sarebbe di tenere la password nella testa... :)

fero86
12-02-2010, 15:15
Per come avete inteso voi la questione della password, la soluzione megliore sarebbe di tenere la password nella testa... :) esattamente: non é difficile tenere a mente l'equivalente di 8 caratteri ASCII (un long occupa 8 byte).

da quanto ho capito il problema é solo quello della verifica: la tua tecnica crittografica sará password-based, peró se l'utente specifica una password errata tu non vuoi restituirgli un plaintext errato, ma vuoi essere in grado di dirgli che quella password era errata. é presto detto: assieme alle password cripta anche una stringa predefinita, per esempio il nome del programma; se l'utente specifica una password errata il nome del programma molto probabilmente verrá decriptato in maniera errata.

fai molta attenzione nel criptare una stringa predefinita: assumi che l'avversario la conosca. se la XORri direttamente con gli 8 byte della chiave l'avversario sará in grado di calcolare la chiave con uno XOR. la stringa predefinita deve essere criptata con le stesse modalitá delle password: deve essere concatenata al resto del plaintext e XORrata con i corrispondenti bytes della sequenza pseudocasuale.

per semplificare il tutto io ti suggerirei di usare si la serializzazione, ma di costruire l'ObjectOutputStream al di sopra di un tuo XorOutputStream che eredita FilterOutputStream e che fa lo XOR dei byte che gli arrivano bit a bit con i byte della sequenza pseudocasuale. lo XorOutputStream poi lo costruisci al di sopra del FileOutputStream. una volta che hai questa infrastruttura basta che usi il metodo ObjectOutputStream.writeUTF per serializzare prima la stringa predefinita e poi un oggetto Iterable<String> di password; come implementazione di Iterable<String> va bene pure LinkedList<String>.

Speed_89
12-02-2010, 21:43
esattamente: non é difficile tenere a mente l'equivalente di 8 caratteri ASCII (un long occupa 8 byte).

da quanto ho capito il problema é solo quello della verifica: la tua tecnica crittografica sará password-based, peró se l'utente specifica una password errata tu non vuoi restituirgli un plaintext errato, ma vuoi essere in grado di dirgli che quella password era errata. é presto detto: assieme alle password cripta anche una stringa predefinita, per esempio il nome del programma; se l'utente specifica una password errata il nome del programma molto probabilmente verrá decriptato in maniera errata.

fai molta attenzione nel criptare una stringa predefinita: assumi che l'avversario la conosca. se la XORri direttamente con gli 8 byte della chiave l'avversario sará in grado di calcolare la chiave con uno XOR. la stringa predefinita deve essere criptata con le stesse modalitá delle password: deve essere concatenata al resto del plaintext e XORrata con i corrispondenti bytes della sequenza pseudocasuale.

per semplificare il tutto io ti suggerirei di usare si la serializzazione, ma di costruire l'ObjectOutputStream al di sopra di un tuo XorOutputStream che eredita FilterOutputStream e che fa lo XOR dei byte che gli arrivano bit a bit con i byte della sequenza pseudocasuale. lo XorOutputStream poi lo costruisci al di sopra del FileOutputStream. una volta che hai questa infrastruttura basta che usi il metodo ObjectOutputStream.writeUTF per serializzare prima la stringa predefinita e poi un oggetto Iterable<String> di password; come implementazione di Iterable<String> va bene pure LinkedList<String>.

Non ci avevo proprio pensato a questo metodo della frase predefinita! :)
Proverò come hai detto! Grazie mille! :)

PS: fero86, mi sembra che tu te ne intenda di programmazione java, scusa la sfacciataggine, ma vorrei chiederti di togliermi un dubbio... Ti mando un messaggio privato...