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

Asked

Viewed 3,655 times

5

I need to do an encryption with the AES algorithm by testing the runtime according to key sizes (128-192-256), but I’m not able to find how to switch the key size to be generated by the system, because my code returns that the key size is 40 bytes or 37 bytes for the 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...");  
}  
}  
  • Welcome to Stack Overflow, Dainara! Please review your code as it does not currently compile. A compileable code can make it much easier for our colleagues to solve the problem!

  • Thank you Daniel. What error does it generate for you? On my computer it is running correctly. There in main have to be exchanged the paths specified in the variables directoryPath, imgOriginal, imgEncriptada and imgDecriptada, I have not treated that part. There is also the question that for keys larger than 128 bits need to download the JCE extension, otherwise it does not even compile.

1 answer

6


I believe the problem with your code is only on the way out:

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

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

But there is the method getEncoded(), that seems to return what you want.

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

Teste utilizando 128 bits

And using 256 bits, the result is this:

Teste utilizando 256 bits

Note that the key size has changed from 16 to 32 bytes. Follow the changed code:

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

public class EncriptaDecriptaAES {

    KeyGenerator keygenerator = null;
    Cipher cifraAES = null;
    SecretKey chaveAES = null; 
    static String IV = "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...");

    }
}

Heed:

  • I commented on the part that opens different images and used a code that works always on the same image (as a test).
  • Included a new method to convert bytes to hexadecimal. I found it here.
  • I changed my System.currentTimeMillis(); for System.nanoTime(); on the recommendation of several 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 don’t totally trust the code I posted... ;)
  • If you can comment on your test results, I’d appreciate it!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.