Oppure

Loading
Questo topic e' stato chiuso dal moderatore.
05/11/09 22:24
Furion
Salve ragazzi, vorrei porvi questo quesito: sto sviluppando un software tuttofare, una sorta di raccolta di utility, di cui una dovrebbe essere quella di crittaggio tramite AES. Ho trovato un modulo su internet per implementare questo algoritmo ed inzialmente avevo fatto in modo che il mio sw leggesse tutto il file sorgente (es. quello da crittare) e lo crittasse e poi riscrivesse su un nuovo file in un colpo. Ovviamente, però, provando a leggere un file più grande (ho provato con un file di circa 1 Gb e mezzo), il sw ha crashato sollevando la System.OutOfMemoryException (giustamente direi). Allora ho pensato di risolvere avviando un ciclo del genere (scrivo tipo pseudocodice xkè è tardi):

dim buff(1024) as byte
dim readed as ulong = 0
dim info as FileInfo = <File Sorgente>
dim sourceStream as FileStream = info.Open
dim outStream as FileStream = File.Create(fileDiDestinazione)
dim pass as string = "NoNlEgGeRe"
while (readed < info.Length)
' leggo nuovi dati
readed += sourceStream.read(buff, 0, buff.length)
' AES è il nome del modulo che ho scritto/trovato ed Encrypt è la funzione di crittaggio
' Encrypt vuole la stringa da crittare e la password. Pensa da solo a richiamare i
' due metodi private per creare la chiave e l'IV.
buff = Encoding.Default.GetBytes(AES.Encrypt(Encoding.Default.GetString(buff), pass))
' scrivo i dati crittati
outStream.Write(buff, 0, buff.Length)
end while

Il codice non è proprio quello che sto usando, cmq sta di fatto che finchè tentavo di crittare il file leggendolo in un colpo solo (facendo "sourceStream.Read(buff, 0, info.Length)";) e poi passandolo alla funzione di crittaggio con le stesse modalità di codifica che ho scritto, funzionava tutto. Adesso non funziona nulla, o meglio: il processo va a buon fine (secondo lui) ma ho notato che se prima (leggendo e crittando tutto insieme) il file risultante era grande circa il doppio di quello originario, adesso la dimensione finale è addirittura inferiore. Infatti, se poi si prova a decrittare quanto ottenuto (con un ciclo del tutto simile) il sw mi solleva un'eccezione che purtroppo al momento non ricordo. Cos'è che sbaglio? Grazie a tutti in anticipo :hail:
aaa
06/11/09 19:57
Il Totem
Gli algoritmi di crittazione lavorano solitamente su flussi binari di dati. Tu ottieni una stringa, ma può darsi che nella crittazione parte dell'informazione si stata trasformata in blocchi contenenti bytes terminatori che hanno troncato la stringa, diminuendone la lunghezza. Usa Binary Writer e Reader, oppure un semplice FileStream per lavorare su dati binari.
Inoltre, AES mi sembra un algoritmo simmetrico, ma nel caso usassi qualcos'altro non è sicuro che la dimensione dei blocchi di input sia uguale a quella di output, quindi crittare a blocchi non è consigliabile (perchè poi non sapresti come tornare indietro).
aaa
06/11/09 20:25
Furion
Allora, intanto grazie per la risposta ed il conseguente interessamento. Mi sembra doveroso fare qualche altra precisazione: innanzitutto il fatto di passare una stringa all'AES non è una mia idea, ma di chi ha scritto il modulo che ho trovato di cui scrivevo nel post precedente. In effetti, vedendo questa soluzione, anch'io ho pensato alle stesse cose che mi hai detto, però ho voluto provare ugualmente. Seconda cosa, in effetti oltre all'AES sto usando un altro piccolo giochino sui byte. Terza ed ultima cosa, il buffer che uso, in realtà, ha una dimensione di 16 Mb esatti (16.777.216 byte): questo perchè ho visto che se riesco a caricare tutto il file sorgente in memoria ed a crittarlo con un unica istruzione, il mio "giochino" e l'AES (nonostante il fatto della stringa) lavorano benissimo di comune accordo. In pratica quello che il mio sw fa è questo

SE fileSorgente.dimensione <= 16 Mb
arrayDiByte = leggiTutto(fileSorgente)
arrayDiByte = crittaConMioAlgoritmo(arrayDiByte)
arrayDiByte = crittaConAES(arrayDiByte)
scriviSuNuovoFile(arrayDiByte)
ALTRIMENTI
avvia ciclo di crittaggio a blocchi

Ora il dubbio è: perchè se viene eseguito il primo ramo dell'if funziona tutto? Ti sarebbe di troppo disturbo, inoltre, scrivermi un piccolo esempio (pure in pseudocodice va bene) con le classi che mi hai suggerito? Grazie molte Totem.
Ultima modifica effettuata da Furion 06/11/09 20:26
aaa
07/11/09 9:20
Il Totem
Qui:
totem.altervista.org/guida/versione2/…
C'è un mio esempio che usa l'algoritmo Rinjdael (AES) con dati binari. Il metodo accetta come input un testo solo perchè l'esempio doveva crittare un testo, ma vedi bene che nel corpo della funzione viene convertito in array di byte, quindi puoi modificare la signature di conseguenza.

Qui:
totem.altervista.org/guida/versione2/…
C'è un esempio sui file binari, ma vedo che hai usato anche tu un FileStream e non dovresti avere problemi.
aaa
07/11/09 19:05
Furion
Grazie Totem. Appena ho una attimo di tempo provo a vedere la questione dell'AES e vedo se cambiando il mio reader (io uso un FileStream per leggere e non un BinaryReader) riesco a tirare fuori qualche ragno dal buco. Grazie ancora.
aaa
19/11/09 21:29
Furion
Ragazzi scusate il doppio post e la risposta così tardiva. Volevo solo ringraziare Totem xkè la sua risposta mi ha aiutato ha risolvere: in pratica aveva ragione quando parlava della dimensione del blocco da passare all'AES. L'ho corretta ed ora funziona tutto. Ho deciso di rispondere alla discussusione perchè potrebbe essere utile ad altri. Ciao a tutti
aaa