CipherInputStream is Empty when trying to decrypt file - java

I'm trying to write a few helper methods to take care of reading and writing an encrypted file. I have two methods which successfully fulfill this and return an InputStream or an OutputStream (which are really the Cipher version) that I can use to read or write to the file. I have confirmed that these methods work peachy keen when wrapped with an Object stream and used to read and write an encrypted Object to file.
However, the problem arises when I try to read from an encrypted text file. I can verify that the String I feed it is being encrypted and written to the correct file, but when I try to read back from this file, the BufferedReader reports an EOF (null). The InputStream.available() method returns 0. I can assure that the file is there, is being found, and that the InputStream itself is not null. Can anybody tell me what might cause this?
Reading/Writing encrypted Object works beautifully (CorruptedStreamException is good here):
private static void testWriteObject() {
String path = "derp.derp";
Derp start = new Derp("Asymmetril: " + message, 12543, 21.4, false);
FilesEnDe.writeEncryptedObject(key, "derp.derp", start);
echo("original");
echo(">"+start);
Object o;
try {
ObjectInputStream ois = new ObjectInputStream(ResourceManager.getResourceStatic(path));
o = ois.readObject();
echo("encrypted");
echo(">"+o);
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
o = FilesEnDe.readEncryptedObject(key, path);
echo("decrypted");
echo(">"+o);
}
Output:
original
>Asymmetril: WE CAME, WE SAW, WE CONQUERED.; 12543; 21.4; false
[RM] > Trying to load resource: derp.derp
java.io.StreamCorruptedException
[RM] > Trying to load resource: derp.derp
decrypted
>Asymmetril: WE CAME, WE SAW, WE CONQUERED.; 12543; 21.4; false
Trying to decrypt the text file doesn't (note that the encrypted text is readable):
private static void testWriteFile() {
String path = "EncryptedOut.txt";
BufferedReader bis1, bis2;
try {
BufferedOutputStream os = new BufferedOutputStream(FilesEnDe.getEncryptedOutputStream(key, path));
os.write(message.getBytes());
os.flush();
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
echo("original");
echo(">"+message);
try {
bis1 = new BufferedReader (new InputStreamReader(ResourceManager.getResourceStatic(path)));
echo("encrypted");
echo(">" + bis1.readLine());
bis1.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
InputStream is = FilesEnDe.getEncryptedInputStream(key, path);
InputStreamReader isr = new InputStreamReader(is);
bis2 = new BufferedReader (isr);
echo("bits in stream? " + is.available());
echo("decrypted");
echo(">"+bis2.readLine());
bis2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Output:
original
>WE CAME, WE SAW, WE CONQUERED.
encrypted
>¤ƒ]£¬Vß4E?´?ùûe
[RM] > Trying to load resource: EncryptedOut.txt
bytes in stream? 0
decrypted
>null
The code used to create the CipherInputStream:
public static InputStream getEncryptedInputStream(String key, String path) {
try {
InputStream is = ResourceManager.getResourceStatic(path);
SecretKeySpec keyspec = new SecretKeySpec(getHash(key),"AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, keyspec);
return new CipherInputStream(is,c);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
THE PROBLEM OCCURS WHEN I TRY TO USE A CIPHERINPUTSTREAM TO DECRYPT THE FILE AND RETRIEVE THE ORIGINAL STRING.

However, the problem arises when I try to read from an encrypted text file.
There is no such thing as an 'encrypted text file'. The result of encryption is binary, not text.
I can verify that the String I feed it is being encrypted and written to the correct file, but when I try to read back from this file, the BufferedReader reports an EOF (null).
You shouldn't be using a BufferedReader. It isn't text, it is binary. Use a BufferedInputStream.

It didn't matter whether I wrote via a PrintWriter or a BufferedOutputStream, nor whether I read with a Reader or not. Turns out, I forgot to close the OutputStream that created the file. As soon as I added that one little line, everything began working. Thank you to Antoniossss for suggesting I redo the broken part of my method. I wonder why Eclipse didn't mention a resource leak about it...

Related

How do I prevent a file from corrupting when I transfer it over a local network using sockets?

I am working on a school project where I want to make a personal storage server. At the moment, what I am trying to achieve is being able to transfer a file from the client machine to the server. However, when testing this with an image, the file partially sends before it corrupts.
Please bare in mind that I am a reasonably new programmer and that my technical knowledge may be some-what limited.
I am using a byte array through a DataOutputStream to transfer the file. I want to use this method as it should work for any file type. I've tried to set the buffer size to the exact size of the file and larger but neither have worked.
Server:
public void run() {
try {
System.out.println("ip: " + clientSocket.getInetAddress().getHostAddress());
out = new DataOutputStream(clientSocket.getOutputStream());
in = new DataInputStream(clientSocket.getInputStream());
in.read(buffer, 0, buffer.length);
fileOut = new FileOutputStream("X:\\My Documents\\My
Pictures\\gradient.jpg");
fileOut.write(buffer, 0, buffer.length);
in.close();
out.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
Client:
public void startConnection(String ip, int port) {
try {
clientSocket = new Socket(ip, port);
out = new DataOutputStream(clientSocket.getOutputStream());
in = new DataInputStream(clientSocket.getInputStream());
x = false;
Path filePath = Paths.get("C:\\Users\\georg\\Documents\\gradient.jpg");
buffer = Files.readAllBytes(filePath);
Thread.sleep(3000);
//Files.write(filePath, buffer);
//out.write(buffer,0,buffer.length);
x = true;
sendMessage(buffer);
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (InterruptedException ex) {
Logger.getLogger(PCS_Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
public byte[] sendMessage(byte[] buffer) {
if (x==true){
try {
out.write(buffer,0,buffer.length);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
return null;
}
Here is a comparison of the files I've tried to send vs the files I receive:
https://imgur.com/gallery/T7nUUJT
Curiously, sending a single colour image produces a single colour image on the server. I believe the issue here may have to be in the timing of code execution however I am not sure and do not know how to go about fixing it.
The issue is in your server code, at this line:
in.read(buffer, 0, buffer.length);
You expect to read all the data at once, but if you read the doc you will find this:
public final int read(byte[] b,
int off,
int len)
throws IOException
Reads up to len bytes of data from the contained input stream into an
array of bytes. An attempt is made to read as many as len bytes, but a
smaller number may be read, possibly zero. The number of bytes
actually read is returned as an integer.
The important part is Reads up to len bytes of data.
You must use the return value of read and call it read repeatedly until the is nothing more to read.

Reading a resource file from within compiled jar, return as file

I've read this Reading a resource file from within jar however I couldn't figure out how to get a file instead of a inputstream, which is what I need. This is the code:
private void duplicateDocument() {
FileOutputStream fos = null;
File file;
try {
try {
doc = new File(getClass().getResource("1.docx").toURI());
//doc = new File(getClass().getResourceAsStream("1.docx"));
} catch (URISyntaxException ex) {
Logger.getLogger(ForensicExpertWitnessReportConfigPanel.class.getName()).log(Level.SEVERE, "Failed ...", ex);
}
file = new File("C:\\Users\\student\\Documents\\myfile.docx");
fos = new FileOutputStream(file);
/* This logic will check whether the file
* exists or not. If the file is not found
* at the specified location it would create
* a new file
*/
if (!file.exists()) {
file.createNewFile();
}
/*String content cannot be directly written into
* a file. It needs to be converted into bytes
*/
byte[] bytesArray = FileUtils.readFileToByteArray(doc);
fos.write(bytesArray);
fos.flush();
System.out.println("File Written Successfully");
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally {
try {
if (fos != null)
{
fos.close();
}
}
catch (IOException ioe) {
System.out.println("Error in closing the Stream");
}
}
}
FileUtils.readFileToByteArray is the only thing I've been able to get working so far, which is why I need the value a a file rather than an inputstream.
Currently, the code above gives "A java.lang.IllegalArgumentException" which is why I saw a suggestion online to use getResourceAsStream() instead - however haven't been able to return it as a file.
My next option is to try Reading a resource file from within jar - buffered reader instead.
Can someone help?
I recommend Files with its many useful functions:
Path out = Paths.get("C:\\Users\\student\\Documents\\myfile.docx");
InputStream in = getClass().getResourceAsStream("1.docx");
Files.copy(in, out, StandardCopyOption.REPLACE_EXISTING);
A resource in principle is a read-only file, possibly zipped in a jar.
Hence one cannot write back to it, and it can only serve as template for a real file, as is done here.
I got it working, using this:
InputStream in = getClass().getResourceAsStream("1.docx");
byte[] bytesArray = IOUtils.toByteArray(in);

pass byte[] , file parameter to a method java

I m confused to how to pass byte array and file to a method in Java :
when I call enregistre method : enregistre(img3File, file3) and enregistre(img4File, file4) enregistre(img5File, file5) , it doesn t upload the file to the database, but when I call the part of program without method( I repeat the code with :img2File and file2 ) it worked, I dont want to repeat the code 5 times, I beleive there are a solution , help me to figure out what is wrong when I call the method please.
#RequestMapping(value="/save",method=RequestMethod.POST)
public String add (
#RequestParam("photos") MultipartFile file,
#RequestParam("photos2") MultipartFile file2,
#RequestParam("photos3") MultipartFile file3,
#RequestParam("photos4") MultipartFile file4,
#RequestParam("photos5") MultipartFile file5)
{
byte[] img1File=null;
try {
//////////////////////// part1
img1File= file.getBytes();
BufferedOutputStream stream;
stream = new BufferedOutputStream(new FileOutputStream(new File("ben1")));
stream.write(img1File);
stream.close();
//////////////////// end part 1
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// here I repeat the code and I don t want to repeat it
byte[] img2File=null;
try {
//////////////////////// part 2
img2File= file2.getBytes();
BufferedOutputStream stream;
stream = new BufferedOutputStream(new FileOutputStream(new File("ben1")));
stream.write(img2File);
stream.close();
////////////////////////end part 2
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] img3File=null;
enregistre(img3File, file3);
byte[] img4File=null;
enregistre(img4File, file4);
byte[] img5File=null;
enregistre(img5File, file5);
Annonce annonce=new Annonce();
annonce.setPhotos(img1File);
annonce.setPhotos2(img2File);
annonce.setPhotos3(img3File);
annonce.setPhotos4(img4File);
annonce.setPhotos5(img5File);
annoncedao.save(annonce);
return "SuccessAddAnnonce";
// method
public void enregistre(byte[] imgFile,MultipartFile file)
{
try {
imgFile= file.getBytes();
BufferedOutputStream stream;
stream = new BufferedOutputStream(new FileOutputStream(new File("ben1")));
stream.write(imgFile);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Look at what your enregistre method does:
BufferedOutputStream stream;
stream = new BufferedOutputStream(new FileOutputStream(new File("ben1")));
stream.write(imgFile);
stream.close();
If you call that method multiple times, it will write to the same file multiple times. There's no point in that - you'll just end up with the file containing the data for the last call. Note that the method doesn't do anything with a database - it just writes a file. You haven't explained to us where the code that does write to the database is, but presumably it's reading from that file at some point.
(Aside from that, the first parameter of the method is completely useless, as you immediately reassign it. This code has some serious issues in terms of code hygiene, but I've focused just on what you were asking.)

streaming binary files through a communication port

I am pushing binary files through a com port to a module connected to my computer.
right now I am pushing the files one by one every minute and it seems that I should do it using a stream pushing files constantly.
here are my methods for the pushing of the files:
public void push2rec (File F, boolean chk){
try {
byte[] read = BinRead(F.getAbsolutePath());
SP.writeBytes(read);
if (chk) {F.delete();}
}
catch (SerialPortException ex) {msgArea.append(ex.toString() + "\n");}
}
public static byte[] BinRead(String name){
File file = new File(name);
byte[] bytes = new byte[(int) file.length()];
try {
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(bytes);
inputStream.close();
}
catch (FileNotFoundException ex) {System.out.println(ex);}
catch (IOException ex) {System.out.println(ex);}
return bytes;
}
SP is a serial port instance.
my question is what would be the best way to do it. Also would it be possible to feed the same file over and over again using a stream until the next file should be pushed?
a certain file should be pushed every minute, this is very important. That means I can not push many different files in the same minute. it should be a stream of a the same file.

Read/Write File in blackberry

I am writing to a file using this code.
protected void writeFile(String text) {
DataOutputStream os = null;
FileConnection fconn = null;
try {
fconn = (FileConnection) Connector.open("file:///store/home/user/documents/file.txt", Connector.READ_WRITE);
if (!fconn.exists())
fconn.create();
os = fconn.openDataOutputStream();
os.write(text.getBytes());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (null != os)
os.close();
if (null != fconn)
fconn.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}}
the code is working fine.
My problem is if I write first time "Banglore" and when I read it, I get "Banglore".
But, second time when I write "India" and when I read it, I get, "Indialore".
so, basically its content is not changing according the text , I am giving.
Please tell me how to fix this.
writing in a file doesn't remove the content but it just replaces the content, so writing 'india' over 'Bangalore' will replace the 'Banga' with 'India' and the rest would remain the same. If you want to completely remove old content with newer one, you need to truncate()
the file from where the newer data ends. truncate(text.getBytes().length)

Categories