I am doing some file encryption related work. I am able to encrypt/decrypt the files but facing a major performance issue. When I simply read/write a video file of 700 MB size, my code performs at around 27-28 MB/s. But when I perform encryption(I am currently using PBEWithMD5AndDES, which I would be changing later) code shows speeds at 9 MB/s. Please advise as to where can I improve.
Code snippet:
int c = 0, BUF_SIZE = 8192;
byte[] b = new byte[BUF_SIZE];
FileInputStream fis;
DataInputStream dis;
FileOutputStream fos;
DataOutputStream dos;
CipherOutputStream cos;
try {
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, iterationCount);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance(algorithm);
// get key
key = generateKeyFromPassword(password);
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec);
fis = new FileInputStream(inFile);
dis = new DataInputStream(fis);
fos = new FileOutputStream(outFile);
dos = new DataOutputStream(fos);
cos = new CipherOutputStream(fos, pbeCipher);
while ((c = dis.read(b)) > 0) {
cos.write(b);
//dos.write(b);
}
fis.close();
dis.close();
//dos.close();
cos.close();
} catch (Exception e) {
e.printStackTrace();
}
Stats without encryption:
Speed is around 27.97 MB/s
Exact Time = 25.02 sec
File Size = 700 MB
Stats with encryption:
Speed is around 9.69 MB/s
Exact Time = 72.171 sec
File Size = 700 MB
Firstly: if at all possible, don't do this yourself. Encryption is very (very!) easy to mess up in ways that lead to the results being insecure. If at all possible, use an external component or library to do as much of the encryption work as is practical.
Secondly, if you're going to do this yourself as now, don't use DES. DES is no longer a strong-enough cipher. Triple-DES is OK, but what you really want to be using is AES. It's regarded as secure, modern CPUs were kept in mind during its design, you get a choice of key lengths to balance security against performance and modern CPUs have hardware acceleration for AES (AES-NI). (I don't know whether Java uses this, but if it doesn't, it certainly might start to in future, whereas the chances of that for Triple-DES are zero.)
Thirdly, you're reading and writing a byte at a time. Whilst encryption is going to be CPU-intensive in any event, doing it as you are at the moment is going to be slower than necessary. Reading and writing via a byte[]
of 4kB or so should see much better performance.
Try wrapping the data input stream with a buffered input stream for starters. Also check this link for a performance comparison of different algorithms in java. AES will indeed yield a considerably faster result than DES.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With