1

Short Version: I write an 8 byte, byte array filled with random bytes to disk using a DataOutputStream, and then read it back in with a DataInputStream in another method. The data does not appear to be the same. Where should I start looking for problems?

Long Version: I have a piece of code that is doing password based encryption using the javax.crypto libraries. I generate an 8 byte random salt using a random number generator, and then use an iteration count of 1000 to generate the key.

When I write the file, it goes in the format:

[ 8-byte Salt ][int iteration count][encrypted payload]

When I read the beginning of the file to recover the parameters for rebuilding the key, the byte array doesn't appear to be the same as what was written. The iteration count, however is recovered successfully.

The entire piece of code is here:

http://hg.kurt.im/479hw3/src/0c3c11f68f26/src/csc479_hw3/PBE.java

With the relevant pieces below:

boolean encrypt(char[] password, String fileName){
    Random randy = new Random();
    byte[] salt = new byte[8];
    randy.nextBytes(salt);
    System.out.println("Salt: "+salt);

    try{
        File inFile = new File(fileName);
        File outFile = new File(fileName+."encrypted);
        DataOutputStream dOS = new DataOutputStream(new FileOutputStream(outFile));

        dOS.write(salt);
        dOS.flush();
        dOS.writeInt(1000);
        dOS.flush();
        dOS.close();
        /* Snip a bunch of stuff currently commented out related to encryption */
    }catch(Exception e){
         e.printStackTrace();
         return false;
    }
    return true;
}

boolean decrypt(char[] password, string fileName, string outFileName){
    byte[] salt = new byte[8];
    try{
        DataInputStream dIS = new DataInputStream(new FileInputStream(newFile(fileName)));
        dIS.read(salt,0,salt.length);
        int iterationCount = dIS.readInt();

        System.out.println("Recovered salt: "+salt);//Different than above written salt
        System.out.println("Recovered count: "+iterationCount);//Same as above
        /*Snip some more commented out crypto */
    }catch (Exception e){
        e.printStackTrace();
        return false;
    }
    return true;
}

With the crypto code enabled, I get a half decrypted file. Without it, I only get an inconsistent write then read.

Kurt
  • 157
  • 5

1 Answers1

2

You're printing out a byte array just by using its toString() implementation - which doesn't show the data, just a hash code.

Try using Arrays.toString(salt) instead:

System.out.println("Recovered salt: " + Arrays.toString(salt));

(And likewise when writing it out.)

I suspect you'll now see that you've actually been reading the salt correctly all this time.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You would appear to be correct, thanks! Now to track down why my crypto only recovers half the file... – Kurt Jun 05 '11 at 16:53
  • @Jochen: When he's *displaying* the salt: `System.out.println("Salt: "+salt);` – Jon Skeet Jun 05 '11 at 17:01
  • @Kurt for that, use DataInputStream.readFully(). The read() method isn't guaranteed to read more than one byte, and you're not checking the return value that tells you how many bytes it actually read. – user207421 Jun 06 '11 at 01:05