encryption - using CipherOutputStream in Java, encrypted file ends up corrupted -
i doing bachelor thesis on topic of cryptography , costs.
a part of compare different crypto algorithms , cipher modes in terms of runtime , resource cost. wrote small tool should work in 4 steps:
- read input file
- encrypt input file , write new file.
- read , decrypt written encrypted file.
- write copy of decrypted file onto file system.
- compare initial input file , decrypted file see if equal.
it works fine small .txt input file. reason doesn’t work other kind of file. if take image input file, first few pixels good, rest ends corrupted. far understand problem should somehow when initialize cipher or when use streams. tried out comment lines encrypting , decrypting , works in making plain copies of input file identical.
any suggestions welcome, try test them out asap , report results showed up. apologies “hungarian notations”. p use public , l local. way in our company.
so here class:
import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.fileoutputstream; import java.io.ioexception; import java.security.invalidalgorithmparameterexception; import java.security.invalidkeyexception; import java.security.key; import java.security.nosuchalgorithmexception; import java.util.arrays; import java.util.date; import javax.crypto.cipher; import javax.crypto.cipherinputstream; import javax.crypto.cipheroutputstream; import javax.crypto.keygenerator; import javax.crypto.nosuchpaddingexception; import javax.crypto.spec.ivparameterspec; public class aes_cipher_test { public string plocalref = "e:\\test.txt"; public string plocalrefoutput = "e:\\test-crypted.txt"; public string plocalcopyoutput = "e:\\test-neu.txt"; public key pkeyaes = null; public int pbitkey = 128; public cipher pcipher; public fileoutputstream pfos; public fileinputstream pfis; public cipheroutputstream pcos; public cipherinputstream pcis; public file pinputfile = new file(this.plocalref); public file poutputfile = new file(this.plocalrefoutput); public file pgeneratedfile = new file(this.plocalcopyoutput); public aes_cipher_test() { crypt_decrypt_write_file(); } public void crypt_decrypt_write_file() { byte[] lloadedfile = null; byte[] lgeneratedfilebyte = null; try { // generate new random aes key keygenerator lkeygen = keygenerator.getinstance("aes"); lkeygen.init(this.pbitkey); this.pkeyaes = lkeygen.generatekey(); // read input file this.pfis = new fileinputstream(this.pinputfile); fileinputstream tempstream = new fileinputstream(this.pinputfile); int count = 0; while (tempstream.read() != -1){ count ++; } lloadedfile = new byte[count]; // new byte[this.pfis.available()] this.pfis.read(lloadedfile); system.err.println("lloadedfile.legth " + lloadedfile.length); this.pfis.close(); //init cipher aes encrypt mode cfb8 oder ctr this.pcipher = cipher.getinstance("aes/ctr/pkcs5padding"); this.pcipher.init(cipher.encrypt_mode, this.pkeyaes); // build cipher stream fileoutputstream this.pfos = new fileoutputstream(this.poutputfile); this.pcos = new cipheroutputstream(this.pfos, this.pcipher); //write encrypted data stream this.pcos.write(lloadedfile); this.pcos.close(); this.pfos.close(); // init cipher decrypt mode this.pcipher.init(cipher.decrypt_mode, this.pkeyaes, new ivparameterspec(this.pcipher.getiv())); // read written localfile , decrypt this.pfis = new fileinputstream(this.poutputfile); tempstream = new fileinputstream(this.poutputfile); count = 0; while (tempstream.read() != -1){ count ++; } byte[] lbytes = new byte[count];// new byte[this.pfis.available()] this.pcis = new cipherinputstream(this.pfis, this.pcipher); int lbytesread = this.pcis.read(lbytes); while (lbytesread > -1) { lbytesread = this.pcis.read(lbytes); } this.pcis.close(); this.pfis.close(); system.err.println("lbytes.length " + lbytes.length); // write new not crypted file see if procedure works this.pfos = new fileoutputstream(this.plocalcopyoutput); this.pfos.write(lbytes); this.pfos.close(); //compare input file , output file this.pfis = new fileinputstream(this.pgeneratedfile); tempstream = new fileinputstream(this.pgeneratedfile); count = 0; while (tempstream.read() != -1){ count ++; } lgeneratedfilebyte = new byte[count]; // new byte[this.pfis.available()] int = this.pfis.read(lgeneratedfilebyte); this.pfis.close(); system.err.println("lgeneratedfilebyte.length " + i); system.err.println("test if initial file , new file identical = " + arrays.equals(lgeneratedfilebyte, lloadedfile)); } catch (filenotfoundexception e) { throw new runtimeexception("file_does_not_exist", e); } catch (nosuchalgorithmexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (nosuchpaddingexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (invalidkeyexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (invalidalgorithmparameterexception e) { // todo auto-generated catch block e.printstacktrace(); } } public static void main(string args[]) { system.err.println("start aes_cipher_test"); long start = new date().gettime(); new aes_cipher_test(); long runningtime = new date().gettime() - start; system.err.println("end aes_cipher_test"); system.err.println("runtime: " + runningtime); } }
usual series of mistakes.
read()
isn't specified fill buffer. specified transfer @ least 1 byte, or else return -1 indicating end of stream. have loop:while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); }
your existing loop while (!(lbytesread < lbytes.length))
nonsense.
available()
explicitly not total number of bytes in stream, , usage of allocate buffer of such size explicitly stated in javadoc incorrect. again, have loop, see above. there few if uses ofavailable(),
, isn't 1 of them.
Comments
Post a Comment