0

I'm having some issues with sending an encrypted file over a socket (client-server communication). I think this is an issue related with the streams (more specifically the arrangement of streams seems to be rather complex, since I'm making data input/output streams from object input/output streams and then, cipher input/output streams from those)...

Client side:

private static void sendEncrypted(FileInputStream fis,DataOutputStream dos)throws Exception{

try {
        byte[] data = new byte[1024];

        CipherOutputStream cos = new CipherOutputStream(output, c);

        makeFileHeader(dos, c, key, sig);

        int i = fis.read(data);

        while(i != -1){
            cos.write(data, 0, i);
            sig.update(data);
            cos.flush();
            i = fis.read(data);
        }
        cos.close();
        fis.close();

byte[] signatureObj = sig.sign();

        output.writeObject(signatureObj);

    } catch (Exception e) {
        System.out.println(e.toString());
    }
}

dos - created from the original objectoutputstream (output, that was created from the socket) makefileheader - method that creates an object and uses output to write it over

Server side:

private static void receiveFiles(DataInputStream dis,FileOutputStream fos, int size) throws IOException{

        byte [] b = new byte[1024];
        int read = 0;
        int offset;
        while(read < size){
            offset = input.read();
            dis.read(b,0,offset);
            fos.write(b,0,offset);
            read +=offset;
        }

    }
besnico
  • 253
  • 2
  • 4
  • 13
  • 3
    "*I'm having some issues*" is not a good problem description. Please be more specific - post stacktraces if you have them or explain why your outputs look incorrect. Ideally, please create an [SSCCE](http://sscce.org/) that demonstrates the problem which we can copy/paste. – Duncan Jones Apr 30 '13 at 13:36
  • 3
    I see you are writing on `output` directly *after* closing `cos` which is created on top of `output`. As far as I remember this is not possible. From the docu of CipherOutputStream.close(): "This method invokes the doFinal method of the encapsulated cipher object, which causes any bytes buffered by the encapsulated cipher to be processed. The result is written out by calling the flush method of this output stream. This method resets the encapsulated cipher object to its initial state **and calls the close method of the underlying output stream**." – Fildor Apr 30 '13 at 13:50
  • @Fildor that was exactly the problem, thank you so much, and my appologies for not being as specific as I could have been – besnico Apr 30 '13 at 15:05

2 Answers2

1

Adding this answer, so the question can be closed:

I see you are writing on output directly after closing cos which is created on top of output. This is not possible.

From the docu of CipherOutputStream.close(): "This method invokes the doFinal method of the encapsulated cipher object, which causes any bytes buffered by the encapsulated cipher to be processed. The result is written out by calling the flush method of this output stream. This method resets the encapsulated cipher object to its initial state and calls the close method of the underlying output stream."

Fildor
  • 14,510
  • 4
  • 35
  • 67
  • yup, that is the thing ;) BTW, is there a way to force the CipherInputStream to read the last bytes without closing it? Because I'm closing it but then I get an error due to the socket having been closed... – besnico Apr 30 '13 at 17:02
0

sig.update(data);

That should be

sig.update(data, 0, i);
user207421
  • 305,947
  • 44
  • 307
  • 483