Need to confirm its 256 bit file encryption/Decryption or not?

259 Views Asked by At

We have written 256-bit file encryption/decryption code in Java. It's working fine and it properly encrypts and decrypts file with same secret key +salt combination.

import java.io.IOException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.File;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.KeyGenerator;


public class CryptoUtils
{
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES";
    private static final String SECRET_KEY = "ncrm7tDy0Y137YNT4+6/0szt4weszTlqj/iPLySCTKY=";
    private static final String SALT = "ssshhhhhhhhhhh!!!!";
    
    private static void doCrypto256(final int opmode, final File file, final File file2) {       
        try {
            byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");            
            KeySpec spec = new PBEKeySpec (SECRET_KEY.toCharArray(), SALT.getBytes(), 100, 256);
            SecretKey tmp = factory.generateSecret(spec);            
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");           
            Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
            instance.init(opmode, secret,ivspec);             
            final FileInputStream fileInputStream = new FileInputStream(file);
            final byte[] array = new byte[(int)file.length()];
            fileInputStream.read(array);
            final byte[] doFinal = instance.doFinal(array);
            final FileOutputStream fileOutputStream = new FileOutputStream(file2);
            fileOutputStream.write(doFinal);
            fileInputStream.close();
            fileOutputStream.close();
        }
        catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }  
    
    public static void main(String[] args) {     
       File inputFile = new File("D:/JaveEncryptDecrypt/sample.pdf");            
        try {         
          doCrypto256(1, inputFile, inputFile);  //encryption on 256 
         doCrypto256(2, inputFile, inputFile);  //Decryption on 256 
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
    }
}

I have generated an AES-256 secret key, which I have defined inside the class. I want to know if it is 256-bit encryption/decryption or not? If I need to change anything, please let me know.

Thanks

1

There are 1 best solutions below

0
Sohel Tanvir On

there are several points to consider for improving your code:

Hardcoded Secret Key and Salt:

The SECRET_KEY and SALT values should not be hardcoded in the code, especially if this code is to be committed to any public repository. Hardcoded keys and salts are a security risk. It's preferable to read these from a secure external source or configuration at runtime, or even better, to generate them dynamically and store them securely. Initialization Vector (IV):

You're using a static IV (iv), which is not recommended. The IV should be random and unique for each encryption operation to ensure the security properties of CBC mode. The IV doesn't need to be kept secret, but it should be unpredictable. Typically, you would generate a new IV for each encryption, and then prepend it to the ciphertext or send it alongside the ciphertext so that it can be used for decryption. File Handling:

You're reading the entire file into memory, which may not be feasible for large files. You might consider processing the file in chunks instead. You're also overwriting the original file with the encrypted data and then again with decrypted data. This is risky as any failure during the process can lead to data loss. Error Handling:

Instead of just printing the exception message, you should handle exceptions properly. For example, in case of an exception, you might want to ensure that any opened files are closed. Secret Key Derivation:

Your code suggests you're using PBKDF2WithHmacSHA256 to derive a key from the given secret and salt, which is a good practice. However, you should consider increasing the iteration count (currently 100) for added security. The higher the iteration count, the more secure (but slower) the key derivation process will be. Key Verification:

If you want to verify that you're indeed using 256-bit AES, you can check the length of the derived key. For AES-256, the key should be 32 bytes (256 bits) long. To sum up, while you're using AES-256 for encryption, there are various security and efficiency considerations to keep in mind. Consider addressing the above points before deploying this code in a production environment.