IOException, Invalid Stream Header when using SealedObject.getObject()
-
07-12-2019 - |
Question
I'm trying to use SealedObjects to send data over an RMI connection
target is a SealedObject, cipher is initialised beforehand (properly, as far as I'm aware), but when I run the following code, I get an IOException, with the message
invalid stream header: 52FAA4D1
Where 54FAA4D1 is a different 8 character hex string each time.
The code in question is
target.getObject(cipher);
Neither target nor cipher are null - so I presume that the problem is in how my cipher is set up. The key is created in exactly the same way on both the client and server, so I'm at a standstill.
The cipher is created using
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//Do this to get the same parameters as were used on the client side
cipher.init(Cipher.ENCRYPT_MODE, this.key);
AlgorithmParameters parameters = cipher.getParameters();
//Set to decrypt mode using the same parameters
byte[] iv = parameters.getParameterSpec(IvParameterSpec.class).getIV();
cipher.init(Cipher.DECRYPT_MODE, this.key, new IvParameterSpec(iv));
I've tried both with and without using the middle section, and neither seem to work.
If I remove the last parameter in cipher.init() the second time I call it I get an InvalidKeyException, and if I remove the middle section entirely and just use the cipher.getParameters.getParameterSpec(IVParameterSpec.class).getIV(); I get a NullPointerException
So yeah, completely stuck - any help appreciated on even understanding what the problem is would be appreciated.
La solution
When you call cipher.init(Cipher.ENCRYPT_MODE, key)
on the client, a random IV is generated. On the server, the first call to ciper.init
is simply generating a different random IV which does not match the incoming message, so getObject
only sees nonsense.
You need to use the same IV to decrypt each message as was used to encrypt it. In this case you can probably just prepend the IV to the cipher. Then read the IV into a byte array on the server and use it to initialize the decryption.