Always salt AES files. The reason for this is because you have a directory of JPEG files that are encrypted with the same password but have no salt. If someone takes possession of these files, they will see that all files start with the same bytes (since this is a JPEG header, and the same code phrase will always be encrypted to the same values โโuntil the bytes begin to differ, at least with CBC), they will also know that the first blocks of the file will look unencrypted. Even if they donโt know what files they are, they can probably guess the type of the length of the lead in that the different file formats are similar there.
Knowing this, they can reverse engineer your password just like rainbow tables / brute force. Soloing will not stop this, but it will be very difficult to crack, because each file (after salt) will be different, so identifying the file type is difficult, plus they will have to generate a rainbow table for each salt or the computational overhead of creating an initialization vector for the salt.
OpenSSL saves salt in a file
eg. I created the file using this command with the password "password":
echo "randomprhase" | openssl aes-128-cbc -out message.enc
Here is the hexdump of the resulting file: -
[james @web openssltest] $ hexdump message.enc
0000000 6153 746c 6465 5f5f 7eaa c4fd 63d8 8c8c
0000010 9519 75c9 0497 d449 27f5 2c91 0d34 5ceb
0000020
And the same data when I started encryption again: -
[james @web openssltest] $ hexdump message1.enc
0000000 6153 746c 6465 5f5f a876 5394 53f1 bf1a
0000010 adcb e1cd dba9 8034 cf13 8b3f c37c 5048
0000020
The first 4 bytes say that the file is salty ( 6153 746c 6465 5f5f ) and will always be the same.
The next 4 bytes are a random salt ( 7eaa c4fd 63d8 8c8 for the first file and a876 5394 53f1 bf1a for the second file) OpenSSL will take this salt and build the initialization vector (IV), being the MD5 password hash + salt, which is repeated 3 times. This IV is then used to encrypt the file. Note that the payload of the last 8 bytes is different in each case.
If we run the same command without shoving it:
[james @web openssltest] $ echo "randomprhase" | openssl aes-128-cbc -nosalt -out nosalt.enc
[james @web openssltest] $ echo "randomprhase" | openssl aes-128-cbc -nosalt -out nosalt1.enc
[james @web openssltest] $ hexdump nosalt.enc
0000000 947e f4ab 6dd7 c548 89e4 b587 82f4 5136
0000010
[james @web openssltest] $ hexdump nosalt1.enc
0000000 947e f4ab 6dd7 c548 89e4 b587 82f4 5136
0000010
Note that when I repeated it using the same password and didnโt point to salt, the payload is identical.
In the Java implementation, you can store your salt separately, but you should spend your time on emulating the OpenSSL implementation, so you do not need to rely on your own code to decrypt the file (especially if you lose your code at some point in the future, encryption may stop you as much as can prevent the attacker).