Reputation: 356
Trying something that envolves partially encrypting a file. All is well except this little problem. For some reason. the flush method does work until n > 52 where n is count of loops. You can see it in the decryption method. If i change the n fomr < 10 to < 53 it flushes. I tested it by looking at the file. no new contents are added until 53. But there should be.
public class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
DesEncrypter(SecretKey key) {
// Create an 8-byte initialization vector
byte[] iv = new byte[]{
(byte)0x8E, 0x12, 0x39, (byte)0x9C,
0x07, 0x72, 0x6F, 0x5A
};
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
try {
ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// CBC requires an initialization vector
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
// Buffer used to transport the bytes from one stream to another
byte[] buf = new byte[1024];
public void encrypt(InputStream in, OutputStream out) {
try {
// Bytes written to out will be encrypted
AppendableOutputStream out_append = new AppendableOutputStream(out);
OutputStream out_c = new CipherOutputStream(out_append, ecipher);
// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
int count = 0;
int max = 1024;
boolean first = true;
while ((numRead = in.read(buf, 0, max)) > 0) {
System.out.println("running Total: " + count);
count += numRead;
// if this read puts as at less than a meg, encrypt
if(count <= 1024*1024){
System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count);
out_c.write(buf, 0, numRead);
// last encryption pass, close buffer and fix max
if(count == 1024*1024){
// fix reading 1k in case max was decreased
max = 1024;
out_c.close();
}
// if next read will go over a meg, read less than 1k
else if(count + max > 1024*1024)
max = 1024*1024 - count;
}
// past the first meg, don't encrypt
else{
System.out.println("processed " + numRead + " of " + max +" bytes : total " + count);
out.write(buf, 0, numRead);
}
}
out.close();
} catch (java.io.IOException e) {}
}
// Movies encrypt only 1 MB 128 passes.
public void decrypt(InputStream in, OutputStream out) {
try {
// Bytes read from in will be decrypted
InputStream in_c = new CipherInputStream(in, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
int count = 0;
int max = 1024;
while ((numRead = in_c.read(buf, 0, max)) > 0) {
count += numRead;
System.out.println("decrypted " + numRead + " of " + max +" bytes : total " + count);
out.write(buf, 0, numRead);
if(count + max > 1024*1024){
max = 1024*1024 - count;
}
if(count == 1024*1024)
max = 0;
}
//in.skip(count);
int n = 0;
while((numRead = in.read(buf)) > 0 && n < 10){
count += numRead;
System.out.println("processed " + numRead + " of 1024 bytes : total " + count);
out.write(buf,0,numRead);
//System.out.println("buf"+buf.length +" numered" + numRead+ " n"+n);
// If i look at the file after anything under n < 51 the file doesn't change.
n++;
}
out.flush();
out.close();
} catch (java.io.IOException e) {
System.out.println("AHHHHHHHH!!!!!!");
}
}
Upvotes: 2
Views: 1498
Reputation: 356
Well for what I was doing it seems that the inputstream in the decryption method was messing with the data. Instead of decrypting it when it was being read back in I decrypted it when it was being processed back out. The padding messed with it a bit too. Had to add an extra 8 bytes to the 1024*1024 code in the decryption method. If anyone cares here are the revised methods Thank you everyone for the help.
public void encrypt(InputStream in, OutputStream out) {
try {
// Bytes written to out will be encrypted
AppendableOutputStream out_append = new AppendableOutputStream(out);
OutputStream out_c = new CipherOutputStream(out_append, ecipher);
// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
int count = 0;
int max = 1024;
boolean first = true;
while ((numRead = in.read(buf, 0, max)) > 0) {
//System.out.println("running Total: " + count);
count += numRead;
// if this read puts as at less than a meg, encrypt
if(count <= 1024*1024){
//System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count);
out_c.write(buf, 0, numRead);
// last encryption pass, close buffer and fix max
if(count == 1024*1024){
// fix reading 1k in case max was decreased
max = 1024;
out_c.close();
}
// if next read will go over a meg, read less than 1k
else if(count + max > 1024*1024)
max = 1024*1024 - count;
}
// past the first meg, don't encrypt
else{
//System.out.println("processed " + numRead + " of " + max +" bytes : total " + count);
out.write(buf, 0, numRead);
}
}
out.flush();
out.close();
} catch (java.io.IOException e) {
System.out.println("AHHHHHHHH!!!!!!111");
}
}
// Movies encrypt only 1 MB 128 passes.
public void decrypt(InputStream in, OutputStream out) {
try {
// Bytes written to out will be decrypted
AppendableOutputStream out_append = new AppendableOutputStream(out);
System.out.println(ecipher.getOutputSize(1024*1024));
OutputStream out_d = new CipherOutputStream(out_append, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
int count = 0;
int max = 1024;
while ((numRead = in.read(buf, 0, max)) > 0) {
count += numRead;
if(count <= ecipher.getOutputSize(1024*1024)){
out_d.write(buf, 0, numRead);
// last encryption pass, close buffer and fix max
if(count == ecipher.getOutputSize(1024*1024)){
// fix reading 1k in case max was decreased
max = 1024;
out_d.close();
}
// if next read will go over a meg, read less than 1k
else if(count + max > ecipher.getOutputSize(1024*1024))
max = ecipher.getOutputSize(1024*1024) - count;
}
// past the first meg, don't decrypt
else{
out.write(buf, 0, numRead);
}
}
out.close();
} catch (java.io.IOException e) {
}
}
Upvotes: 0
Reputation: 1286
With the given information I can only speculate. At least it would be very helpful if you specified what type of OutputStream
out
is when you are calling the decrypt
method. The behavior of the flush()
method varies between different concrete implementations.
For example, if your output stream happens to be a CipherOutputStream
, or some other stream that is connected to that type of stream, then the documentation for its flush()
method states the following (important part emphasized by me):
Flushes this output stream by forcing any buffered output bytes that have already been processed by the encapsulated cipher object to be written out. Any bytes buffered by the encapsulated cipher and waiting to be processed by it will not be written out. For example, if the encapsulated cipher is a block cipher, and the total number of bytes written using one of the write methods is less than the cipher's block size, no bytes will be written out.
That certainly sounds like it could be the cause of your problem. However, as I stated, it would be very helpful to know some more details regarding your specific type of stream.
Upvotes: 1