How to Encrypt with the AES Algorithm using 128-192-256 keys in Java

5

I need to do an encryption with the AES algorithm by testing the runtime according to the sizes of the keys (128-192-256), but I can not find how to toggle the size of the key to be generated by the system, since my code returns that the key size is 40 bytes or 37 bytes for all three.

import java.io.*;  
import java.security.*;  
import java.util.Random;  
import javax.crypto.*;  
import javax.crypto.spec.*;  

public class EncriptaDecriptaAES {  

KeyGenerator keygenerator = null;  
Cipher cifraAES = null;  
SecretKey chaveAES = null;  
SecretKey chaveencriptacao;  
static String IV = "AAAAAAAAAAAAAAAA";  

public EncriptaDecriptaAES(int valorKey) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchProviderException, NoSuchPaddingException {  
keygenerator = KeyGenerator.getInstance("AES");  
keygenerator.init(valorKey);  
chaveAES = keygenerator.generateKey();  
System.out.println(((chaveAES.toString()).getBytes("UTF-8")).length);  
cifraAES = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Cria a cifra   
System.out.println(cifraAES.getBlockSize());  
}  

public void encrypt(String srcPath, String destPath) throws UnsupportedEncodingException, InvalidKeyException, InvalidAlgorithmParameterException, FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException {  
File rawFile = new File(srcPath);  
File imagemEncriptada = new File(destPath);  
InputStream inStream = null;  
OutputStream outStream = null;  
cifraAES.init(Cipher.ENCRYPT_MODE, chaveAES, new IvParameterSpec(IV.getBytes("UTF-8"))); //Inicializa a cifra para o processo de encriptação  
inStream = new FileInputStream(rawFile); //Inicializa o input e o output streams  
outStream = new FileOutputStream(imagemEncriptada);  
byte[] buffer = new byte[256];  
int len;  
while ((len = inStream.read(buffer)) > 0) {  
outStream.write(cifraAES.update(buffer, 0, len)); //Para criptografar/descriptografar vários blocos usa-se o método update().   
outStream.flush();  
}  
outStream.write(cifraAES.doFinal()); //Depois de tudo feito chamamos o método doFinal().   
inStream.close();  
outStream.close();  
}  

public void decrypt(String srcPath, String destPath) throws InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException {  
File encryptedFile = new File(srcPath);  
File decryptedFile = new File(destPath);  
InputStream inStream = null;  
OutputStream outStream = null;  
cifraAES.init(Cipher.DECRYPT_MODE, chaveAES, new IvParameterSpec(IV.getBytes("UTF-8"))); //Inicializa o cipher para decriptografar  
inStream = new FileInputStream(encryptedFile); //Inicializa o input e o output streams  
outStream = new FileOutputStream(decryptedFile);  
byte[] buffer = new byte[256];  
int len;  
while ((len = inStream.read(buffer)) > 0) {  
outStream.write(cifraAES.update(buffer, 0, len));  
outStream.flush();  
}  
outStream.write(cifraAES.doFinal());  
inStream.close();  
outStream.close();  
}  

public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, NoSuchProviderException, InvalidKeyException, InvalidAlgorithmParameterException, IOException, FileNotFoundException, IllegalBlockSizeException, BadPaddingException {  
String directoryPath = "D:\Área de Trabalho\"; //Se mudar o pc, alterar esta linha para o caminho certo  

long tempInicial = 0;  
long tempFinal = 0;  
long dif = 0;  

//EncriptaDecriptaAES chave128 = new EncriptaDecriptaAES(128); //Passa como parametro o tamanho da chave de 128 bits  
EncriptaDecriptaAES chave192 = new EncriptaDecriptaAES(192); //chave de 192 bits  
//EncriptaDecriptaAES chave256 = new EncriptaDecriptaAES(256); //chave de 256 bits  

System.out.println("Iniciando Codificação...");   
tempInicial = System.currentTimeMillis();  
for (int i = 1; i <= 10; i++) {   
String imgOriginal = "veiculo" + i + ".jpg";  
String imgEncriptada = "ImagensCrip\imgEncripAES_" + i + ".jpg"; //Nome do arquivo encriptado  
chave192.encrypt(directoryPath + imgOriginal, directoryPath + imgEncriptada);   
}   
tempFinal = System.currentTimeMillis();  
dif = (tempFinal - tempInicial);  
System.out.println(String.format("Tempo de codificação: %02d segundos", dif/60));  
System.out.println("Codificação Finalizada...");  

tempInicial = 0;  
tempFinal = 0;  
dif = 0;  

System.out.println("Iniciando Decodificação...");  
tempInicial = System.currentTimeMillis();  
for (int i = 1; i <= 10; i++) {  
String imgEncriptada = "ImagensCrip\imgEncripAES_" + i + ".jpg"; //Nome do arquivo encriptado  
String imgDecriptada = "ImagensDecrip\imgDecripAES_" + i + ".jpg"; //Nome do arquivo descriptado  
chave192.decrypt(directoryPath + imgEncriptada, directoryPath + imgDecriptada);  
}   
tempFinal = System.currentTimeMillis();  
dif = (tempFinal - tempInicial);  
System.out.println(String.format("Tempo de codificação: %02d segundos", dif/60));  
System.out.println("Decodificação Finalizada...");  
}  
}  
    
asked by anonymous 15.09.2015 / 21:47

1 answer

5

I think the problem with your code is just in the output:

System.out.println(((chaveAES.toString()).getBytes("UTF-8")).length);

toString() does not seem to be implemented, and seems to return garbage. I tried to print the string and the result was something like [B@6a9c98e8 .

However, there is the getEncoded() method, which seems to return what you want.

Running your code, with some modifications, I got the following result using 128 bits:

And,using256bits,theresultisthis:

Noticethatthekeysizehaschangedfrom16to32bytes.Hereisthechangedcode:

importjava.io.*;importjava.security.*;importjavax.crypto.*;importjavax.crypto.spec.*;publicclassEncriptaDecriptaAES{KeyGeneratorkeygenerator=null;CiphercifraAES=null;SecretKeychaveAES=null;staticStringIV="AAAAAAAAAAAAAAAA";
    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public EncriptaDecriptaAES(int valorKey) throws NoSuchAlgorithmException,
      UnsupportedEncodingException, NoSuchProviderException, NoSuchPaddingException {  

        keygenerator = KeyGenerator.getInstance("AES");
        keygenerator.init(valorKey);
        chaveAES = keygenerator.generateKey();

        // Isso nao parece dar certo!
        // System.out.println(((chaveAES.toString()).getBytes("UTF-8")).length);

        System.out.println();
        System.out.println("Tamanho da chave: " + chaveAES.getEncoded().length);
        System.out.println("Chave: " + bytesToHex(chaveAES.getEncoded()));

        // Cria a cifra
        cifraAES = Cipher.getInstance("AES/CBC/PKCS5Padding");

        System.out.println("Tamanho do bloco: " + cifraAES.getBlockSize());
        System.out.println();

    }

    public void encrypt(String srcPath, String destPath) throws UnsupportedEncodingException,
      InvalidKeyException, InvalidAlgorithmParameterException, FileNotFoundException,
      IOException, IllegalBlockSizeException, BadPaddingException {


        File rawFile = new File(srcPath);  
        File imagemEncriptada = new File(destPath);  
        InputStream inStream = null;  
        OutputStream outStream = null;  
        cifraAES.init(Cipher.ENCRYPT_MODE, chaveAES,
          //Inicializa a cifra para o processo de encriptacao
          new IvParameterSpec(IV.getBytes("UTF-8")));

        //Inicializa o input e o output streams
        inStream = new FileInputStream(rawFile);
        outStream = new FileOutputStream(imagemEncriptada);

        byte[] buffer = new byte[256];  
        int len;  

        while ((len = inStream.read(buffer)) > 0) {  
            //Para criptografar/descriptografar varios blocos usa-se o metodo update().
            outStream.write(cifraAES.update(buffer, 0, len));
            outStream.flush();
        }

        //Depois de tudo feito chamamos o metodo doFinal().
        outStream.write(cifraAES.doFinal());
        inStream.close();
        outStream.close();

    }  

    public void decrypt(String srcPath, String destPath) throws InvalidKeyException,
      InvalidAlgorithmParameterException, UnsupportedEncodingException, FileNotFoundException,
      IOException, IllegalBlockSizeException, BadPaddingException {


        File encryptedFile = new File(srcPath);  
        File decryptedFile = new File(destPath);  
        InputStream inStream = null;  
        OutputStream outStream = null;  

        //Inicializa o cipher para decriptografar
        cifraAES.init(Cipher.DECRYPT_MODE, chaveAES, new IvParameterSpec(IV.getBytes("UTF-8")));

        //Inicializa o input e o output streams
        inStream = new FileInputStream(encryptedFile);
        outStream = new FileOutputStream(decryptedFile);  

        byte[] buffer = new byte[256];  
        int len;  

        while ((len = inStream.read(buffer)) > 0) {  
            outStream.write(cifraAES.update(buffer, 0, len));  
            outStream.flush();  
        }

        outStream.write(cifraAES.doFinal());  
        inStream.close();  
        outStream.close();  

    }

    public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException,
      NoSuchPaddingException, UnsupportedEncodingException, NoSuchProviderException,
      InvalidKeyException, InvalidAlgorithmParameterException, IOException,
      FileNotFoundException, IllegalBlockSizeException, BadPaddingException {

        //Se mudar o pc, alterar esta linha para o caminho certo
        String directoryPath = "";

        long tempInicial = 0;
        long tempFinal = 0;  
        long dif = 0;  

        //Passa como parametro o tamanho da chave de 128, 192 ou 256 bits
        EncriptaDecriptaAES chave = new EncriptaDecriptaAES(256);

        System.out.println("Iniciando Codificacao...");
        tempInicial = System.nanoTime();  

        for (int i = 1; i <= 10; i++) {   
            // String imgOriginal = "imagem_" + i + ".jpg";
        String imgOriginal = "imagem_1.jpg";

            //Nome do arquivo encriptado
            String imgEncriptada = "imgEncripAES_" + i + ".jpg"; 
            chave.encrypt(directoryPath + imgOriginal, directoryPath + imgEncriptada);

        }

        tempFinal = System.nanoTime();
        dif = (tempFinal - tempInicial);
        double segundos = (double)dif / 1000000000.0;

        System.out.println("Tempo de codificacao: " + segundos + " segundos.");
        System.out.println("Codificacao Finalizada...");  

        // tempInicial = 0; 
        // tempFinal = 0;  
        // dif = 0;  

        System.out.println();
        System.out.println("Iniciando Decodificacao...");
        tempInicial = System.nanoTime();  

        for (int i = 1; i <= 10; i++) {  
            String imgEncriptada = "imgEncripAES_" + i + ".jpg"; //Nome do arquivo encriptado  
            String imgDecriptada = "imgDecripAES_" + i + ".jpg"; //Nome do arquivo descriptado  
            chave.decrypt(directoryPath + imgEncriptada, directoryPath + imgDecriptada);  
        }

        tempFinal = System.nanoTime();  
        dif = (tempFinal - tempInicial);
        segundos = (double)dif / 1000000000.0;

        System.out.println("Tempo de decodificacao: " + segundos + " segundos."); 
        System.out.println("Decodificacao Finalizada...");

    }
}

Attention:

  • I commented the part that opens different images and I used a code that works always on top of the same image (as test).
  • Include a new method to convert bytes to hexadecimal. I found it here .
  • I've changed from System.currentTimeMillis(); to System.nanoTime(); by recommending various posts .
  • I tested the code using the same image ten thousand times with the three keys of different sizes and the time did not vary much, which is strange. So do not fully trust the code I posted ...;)
  • If you can comment on the results of your tests, I would appreciate it!
17.09.2015 / 08:56