I want to measure the time it takes to encrypt data in java.
I'm successfully encrypting small data.
But, I don't know how to encrypt large data.
Below is my source.
package com.exam.encrypttest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView tv1;
Button but1;
EditText edit1;
String type = "AES";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit1 = (EditText) findViewById(R.id.edit01);
edit1.setText("ABCDEFGH");
tv1 = (TextView) findViewById(R.id.text01);
but1 = (Button) findViewById(R.id.button01);
but1.setOnClickListener(new ButtonClick());
}
class ButtonClick implements View.OnClickListener {
public void onClick(View v) {
int sel = v.getId();
switch (sel) {
case R.id.button01:
Encryption(edit1.getText().toString(), type);
break;
}
}
private void Encryption(String text, String key) {
long time1 = System.currentTimeMillis();
Cipher cipher;
SecretKeySpec skeySpec;
KeyGenerator kgen;
try {
kgen = KeyGenerator.getInstance(key);
SecretKey skey = kgen.generateKey();
kgen.init(128);
byte[] raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, key);
cipher = Cipher.getInstance(key);
byte[] encrypted = Encrypt(text, skeySpec, cipher);
String sendtext = Base64.encode(encrypted);
long time2 = System.currentTimeMillis();
byte[] abc = Base64.decode(sendtext);
byte[] decrypted = Decrypt(abc, skeySpec, cipher);
long time3 = System.currentTimeMillis();
tv1.setText("Encrypt Time(ms) : "+(time2-time1));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] Encrypt(String data, SecretKeySpec keySpec,
Cipher cipher) throws Exception, ArrayIndexOutOfBoundsException {
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
return encrypted;
}
public byte[] Decrypt(byte[] encrypted_data,
SecretKeySpec keySpec, Cipher cipher) throws Exception,
ArrayIndexOutOfBoundsException {
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decrypted = cipher.doFinal(encrypted_data);
return decrypted;
}
}
}
It's works for small data. But it isn't working for large data.
Please, give me some advise.
Use multiple calls to file:///C:/java/jdk1.7.0/docs/api/javax/crypto/Cipher.html#update(java.nio.ByteBuffer,%20java.nio.ByteBuffer)
and play around with buffer sizes. Finally perform a single call to doFinal
.
You need to define a clear set of parameters before performing any testing, otherwise you are comparing differently generated numbers. Also don't forget that Java relies on the JIT, so for long running applications you may want to perform a number of iterations before measuring (due to JIT optimizations taking place while your application is running).
Note that e.g. Guava has a StopWatch
class which is easier to use than System.currentTimeMillis()
.