Message-Id: <l03010d06b0e57b028a6f@[199.174.156.24]>
Date: Fri, 16 Jan 1998 16:06:20 -0500
To: java-security@web1.javasoft.com
From: Jonathan Knudsen <jonathan@oreilly.com>
Subject: CipherOutputStream flush() bug
Hello,
I believe I've isolated a bug in CipherOutputStream's
flush() method. Specifically, I'm trying to use DES/CFB8
with cipher streams to transmit single bytes over a socket
connection. When I call flush() on the CipherOutputStream,
the data gets mangled somehow. There's a test class at
the bottom of this message so you can reproduce the problem.
Ciao,
Jonathan
----------
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.DESParameterSpec;
import oreilly.jonathan.crypto.*;
public class FlushBug {
public static void main(String[] args) throws Exception {
testFlush(false);
testFlush(true);
}
public static void testFlush(boolean flush) throws Exception {
System.out.println("Flushing will " + (flush ? "" : "not") + " be done.");
System.out.println("Creating a SecureRandom...please be patient.");
SecureRandom sr = new SecureRandom();
// Create new DES key.
KeyGenerator kg = KeyGenerator.getInstance("DES");
kg.init(sr);
Key key = kg.generateKey();
// Generate an IV.
byte[] iv = new byte[8];
sr.nextBytes(iv);
// Create the listening side.
Cipher decrypterJonathan = Cipher.getInstance("DES/CFB8/NoPadding");
DESParameterSpec specJonathan = new DESParameterSpec(iv);
decrypterJonathan.init(Cipher.DECRYPT_MODE, key, specJonathan);
PipedInputStream pipedInJonathan = new PipedInputStream();
InputStream inJonathan = new CipherInputStream(pipedInJonathan,
decrypterJonathan);
// Create the sending side.
Cipher encrypterMichael = Cipher.getInstance("DES/CFB8/NoPadding");
DESParameterSpec specMichael = new DESParameterSpec(iv);
encrypterMichael.init(Cipher.ENCRYPT_MODE, key, specMichael);
PipedOutputStream pipedOutMichael = new PipedOutputStream();
OutputStream outMichael = new CipherOutputStream(pipedOutMichael,
encrypterMichael);
// Wire them up.
pipedOutMichael.connect(pipedInJonathan);
// Write from Michael to Jonathan.
OutputStream out = outMichael;
InputStream in = inJonathan;
byte[] plaintext = "abcdef".getBytes();
for (int i = 0; i < plaintext.length; i++) {
out.write(plaintext[i]);
if (flush) out.flush();
int b = in.read();
String original = new String(plaintext, i, 1);
String result = new String(new byte[] { (byte)b });
System.out.println(" " + original + " -> " + result);
}
}
}