I got an infinite loop in this problem. At first, i was receiving a encrypted file from a server and then decrypt it using cipherInputStream, and this was working well. But then i was a bit annoyed, because for that i always need to create the encrypted file i receive from the server.
Then i thought that CipherInputStream just take an InputStream, no matter if it's a fileInputStream or something else. So i've decided to give him directly the DataInputStream i get from the server (with sockets)
Now, it still nearly work. I receive the data, it is decrypted, but the while loop in my decrpyting method never end, because i is never -1 but always 8. Plus, the decrypted file i get is not totally complete (it miss maybe one or two rows of data at the end).
Here's my decrytpion method:
public static void decrypt(DataInputStream dis, SecretKeySpec aesKey, String filename) throws NoSuchAlgorithmException, NoSuchPaddingException{
Cipher c = Cipher.getInstance("AES");
try {
c.init(Cipher.DECRYPT_MODE, aesKey);
FileOutputStream fos;
CipherInputStream cis;
cis = new CipherInputStream(dis, c);
fos = new FileOutputStream(filename);
byte[] b = new byte[8];
int i = cis.read(b);
while (i != -1) {
fos.write(b, 0, i);
i = cis.read(b);
System.out.println(i);
}
fos.close();
cis.close();
new File(filename);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
System.out.println("clé incorrecte.");
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
my dis is:
DataInputStream dis = new DataInputStream(socket.getInputStream());
And here the code to send out the file from the DB on server:
public void sendFile(String fileID, String owner, Socket clientSocket) {
String sql = "SELECT file FROM files WHERE owner LIKE '" + owner + "' AND filename LIKE '"+ fileID + "'";
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)){
DataOutputStream dOut = new DataOutputStream(clientSocket.getOutputStream());
if(rs.next()) {
InputStream input = rs.getBinaryStream("file");
int count;
byte[] buffer = new byte[4096];
while ((count = input.read(buffer)) > 0)
{
dOut.write(buffer, 0, count);
}
}
else
System.err.println("File not found in DB!");
} catch (SQLException | IOException e) {
System.out.println(e.getMessage());
}
}
I've tried a buffer of 4096 in the cipher code; then i will be always 512 except for the last one. So the input does have an end, but the -1 doesn't happen as it should (as says in Javadoc: If no byte is available because the end of the stream has been reached, the value -1 is returned )
Anyone have an idea?