www.pudn.com > encryption.rar > CipherInputStream.java


/*
Christoforos Pirillos @ Villanova University - May 1999
based on code from the book "Java Network Programming" by Hughes
*/

package encryption;
import java.io.*;

/**This is the corresponding class that decrypts stream data. It attaches
to an InputStream and decrypts data from it; data must be in the format
that is written by CipherOutputStream. The Cipher that performs the
decryption is specified in the constructor*/

public class CipherInputStream extends InputStream {

protected ByteArrayInputStream byteI;
protected DataInputStream dataI;
protected Cipher c;

public CipherInputStream (InputStream i, Cipher c) {
	dataI = new DataInputStream (i);
	this.c = c;
	byte[] nothing = new byte[0];
	byteI = new ByteArrayInputStream (nothing);
}

/**reads a single byte from the InputStream.*/

public int read() throws IOException {
	if (byteI.available() ==0)
		readEncrypted();
	return byteI.read();
}

/**reads a subarray from the InputStream*/

public int read (byte[] b, int o, int l) throws IOException {
	if (byteI.available()==0)
		readEncrypted();
	return byteI.read (b,o,l);
}

/**returns the number of bytes that are currently available in the
InputStream buffer*/

public int available () throws IOException {
	return byteI.available();
}

/**attempts to skip over the specified number of bytes*/

public long skip (long n) throws IOException {
	if (byteI.available()==0)
		readEncrypted();
	return byteI.skip(n);
}

public void close () throws IOException {
	dataI.close();
}

/**Reads a chunk of encrypted data, decrypts it and makes it available to
read from the buffer byteI*/

protected void readEncrypted () throws IOException {
	int n = c.blockSize();
	byte[] b = new byte [((4+n-1) /n) *n];
	try {
		dataI.readFully (b);
	}catch (EOFException ex) {
	return;
	}
	byte[] d = c.decipher (b);
	int l = Crypt.bytesToInt (d,0);

	if (l <= b.length) {
		byteI = new ByteArrayInputStream (d,4,l-4);
	} else {
		b = new byte [((l-b.length+n-1)/n)*n];
		dataI.readFully (b);
		byte[] d2 = c.decipher (b);
		b = new byte[l-4];
		System.arraycopy (d,4,b,0,d.length-4);
		System.arraycopy (d2,0,b,d.length-4,l-d.length);
		byteI = new ByteArrayInputStream (b);
	}
}

} /* end of class CipherInputStream */