- How to do Encryption and Decryption of a File?
- 1 Answer 1
- How to Encrypt and Decrypt files in Java 10
- Reference Tutorials
- Create a text.txt file in a specific folder
- Encryption
- Decryption
- Here is the code for encrypt and decrypt a file using AES
- Java File Encryption and Decryption Simple Example
- 1. Basic Steps
- 2. The CryptoUtils class
- 3. The CryptoUtilsTest class
- 4. Note about key size
- References:
- Other Java Coding Tutorials:
- About the Author:
- Add comment
- Comments
How to do Encryption and Decryption of a File?
I use CipherOutputStream to encryption and decryption file in java, but input file > 117 byte cannot encryption. I use RSA algorithm public key lenght 1024 byte.
cipher.init(Cipher.ENCRYPT_MODE, secKey); String cleartextFile = "cleartext.txt"; String ciphertextFile = "ciphertextSymm.txt"; FileInputStream fis = new FileInputStream(cleartextFile); FileOutputStream fos = new FileOutputStream(ciphertextFile); CipherOutputStream cos = new CipherOutputStream(fos, cipher); byte[] block = new byte[8]; int i; while ((i = fis.read(block)) != -1) < cos.write(block, 0, i); >cos.close();
RSA is not designed to encrypt files. Just use a symmetric algorithm (AES, Blowfish, etc.) to encrypt your file, and use RSA only on that symmetric key, if you need symmetric encryption.
1 Answer 1
You cannot encrypt a file using RSA because RSA (well, to be more precise, the implementation of RSA in Java) does not let you encrypt more data than the length of the key. For a 1024 bits key, you can only encrypt 1024 bits that is to say 128 bytes (actually a bit less for padding reasons).
In all cases, it is bad practice to encrypt a large piece of data using a public-key algorithm (asymmetric cryptography) for two main reasons.
- The is no practical, appropriate and secure cryptographic mode/padding to encrypt large amounts of data using RSA (ie it is not really secure to do that).
- Public-key algorithms require a large key to be secure (1024 bits, 2048 bits) and are therefore much slower than symmetric-key algorithms (which only require 128 to 256 bits keys to be secure).
If you want more details on why you should not use solely RSA to encrypt large amounts of data, see these two great stacktexchange posts :
If you want to encrypt a large amount of data, the standard way to proceed is to generate a session key (a cryptographically secure random number used once). You encrypt the session key with the public key. Then you encrypt the file (the large amount of data) with a symmetric algorithm (such AES) using the unencrypted session key. You then store the encrypted session key and the encrypted data altogether in the final file. That’s the way PGP (or GnuPG) proceeds when it sends an encrypted mail. SSL/TLS also works in a similar way.
Lastly, properly using cryptography is complicated (pretty much anything can create a security flaw : encryption modes, padding, etc. ) so I would advise you to be very careful and make sure your code is going to be reviewed by someone knowledgeable in crypto matters.
Here is a piece of code that shows the general process :
// 1. Generate a session key KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(128) SecretKey sessionKey = keyGen.generateKey(); // 2. Encrypt the session key with the RSA public key Cipher rsaCipher = Cipher.getInstance("RSA"); rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey) byte[] encryptedSessionKey = rsaCipher.doFinal(sessionKey.getEncoded()); // 3. Encrypt the data using the session key (unencrypted) Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); aesCipher.init(Cipher.ENCRYPT_MODE, sessionKey);
How to Encrypt and Decrypt files in Java 10
In this tutorial, we show you how to encrypt and decrypt a file using AES in Java 10 Example. We’ll encrypt the text.txt file using your secret key with the Advanced Encryption Standard (AES) as the symmetric encryption algorithm. Then we decrypt this file using the same secret key.
Reference Tutorials
Create a text.txt file in a specific folder
This is a file used for testing encryption and decryption
Encryption
First, we'll create an instance of the Cipher class using the encryption algorithm called AES.
var cipher = Cipher.getInstance("AES");
Next, we will initialize a Cipher by calling its init() method with Cipher.ENCRYPT_MODE and your secret key as parameters:
cipher.init(Cipher.ENCRYPT_MODE, key);
var fileInput = new File(fileInputPath); var inputStream = new FileInputStream(fileInput); var inputBytes = new byte[(int) fileInput.length()]; inputStream.read(inputBytes);
var outputBytes = cipher.doFinal(inputBytes);
var fileEncryptOut = new File(fileOutPath); var outputStream = new FileOutputStream(fileEncryptOut); outputStream.write(outputBytes); inputStream.close(); outputStream.close();
public static void encryptedFile(String secretKey, String fileInputPath, String fileOutPath) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException
Decryption
Same as in the example above. First, we'll create an instance of the Cipher class using the encryption algorithm called AES.
var cipher = Cipher.getInstance("AES");
Next, we will initialize a Cipher by calling its init() method with Cipher.DECRYPT_MODE and your secret key as parameters:
cipher.init(Cipher.ENCRYPT_MODE, key);
var fileInput = new File(fileInputPath); var inputStream = new FileInputStream(fileInput); var inputBytes = new byte[(int) fileInput.length()]; inputStream.read(inputBytes);
var outputBytes = cipher.doFinal(inputBytes);
var fileEncryptOut = new File(fileOutPath); var outputStream = new FileOutputStream(fileEncryptOut); outputStream.write(outputBytes); inputStream.close(); outputStream.close();
public static void decryptedFile(String secretKey, String fileInputPath, String fileOutPath) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException
Here is the code for encrypt and decrypt a file using AES
package com.jackrutorial; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; public class EncryptDecryptFileExample < public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException < var key = "jackrutorial.com"; System.out.println("File input: " + "D:\\text.txt"); //encryptedFile encryptedFile(key, "D:\\text.txt", "D:\\text.enc"); //decryptedFile decryptedFile(key, "D:\\text.enc", "D:\\text-decrypt.txt"); >public static void encryptedFile(String secretKey, String fileInputPath, String fileOutPath) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException < var key = new SecretKeySpec(secretKey.getBytes(), "AES"); var cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); var fileInput = new File(fileInputPath); var inputStream = new FileInputStream(fileInput); var inputBytes = new byte[(int) fileInput.length()]; inputStream.read(inputBytes); var outputBytes = cipher.doFinal(inputBytes); var fileEncryptOut = new File(fileOutPath); var outputStream = new FileOutputStream(fileEncryptOut); outputStream.write(outputBytes); inputStream.close(); outputStream.close(); System.out.println("File successfully encrypted!"); System.out.println("New File: " + fileOutPath); >public static void decryptedFile(String secretKey, String fileInputPath, String fileOutPath) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException < var key = new SecretKeySpec(secretKey.getBytes(), "AES"); var cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); var fileInput = new File(fileInputPath); var inputStream = new FileInputStream(fileInput); var inputBytes = new byte[(int) fileInput.length()]; inputStream.read(inputBytes); byte[] outputBytes = cipher.doFinal(inputBytes); var fileEncryptOut = new File(fileOutPath); var outputStream = new FileOutputStream(fileEncryptOut); outputStream.write(outputBytes); inputStream.close(); outputStream.close(); System.out.println("File successfully decrypted!"); System.out.println("New File: " + fileOutPath); >>
Java File Encryption and Decryption Simple Example
Encryption and decryption are fundamental requirements of every secure-aware application, therefore the Java platform provides strong support for encryption and decryption through its Java Cryptographic Extension (JCE) framework which implements the standard cryptographic algorithms such as AES, DES, DESede and RSA. This tutorial shows you how to basically encrypt and decrypt files using the Advanced Encryption Standard (AES) algorithm. AES is a symmetric-key algorithm that uses the same key for both encryption and decryption of data.
1. Basic Steps
- Create a Key from a given byte array for a given algorithm.
- Get an instance of Cipher class for a given algorithm transformation. See document of the Cipher class for more information regarding supported algorithms and transformations.
- Initialize the Cipher with an appropriate mode (encrypt or decrypt) and the given Key .
- Invoke doFinal(input_bytes) method of the Cipher class to perform encryption or decryption on the input_bytes , which returns an encrypted or decrypted byte array.
- Read an input file to a byte array and write the encrypted/decrypted byte array to an output file accordingly.
2. The CryptoUtils class
Here’s a utility class that provides two utility methods, one for encrypt a file and another for decrypt a file:
package net.codejava.crypto; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; /** * A utility class that encrypts or decrypts a file. * @author www.codejava.net * */ public class CryptoUtils < private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES"; public static void encrypt(String key, File inputFile, File outputFile) throws CryptoException < doCrypto(Cipher.ENCRYPT_MODE, key, inputFile, outputFile); >public static void decrypt(String key, File inputFile, File outputFile) throws CryptoException < doCrypto(Cipher.DECRYPT_MODE, key, inputFile, outputFile); >private static void doCrypto(int cipherMode, String key, File inputFile, File outputFile) throws CryptoException < try < Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(cipherMode, secretKey); FileInputStream inputStream = new FileInputStream(inputFile); byte[] inputBytes = new byte[(int) inputFile.length()]; inputStream.read(inputBytes); byte[] outputBytes = cipher.doFinal(inputBytes); FileOutputStream outputStream = new FileOutputStream(outputFile); outputStream.write(outputBytes); inputStream.close(); outputStream.close(); >catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | IOException ex) < throw new CryptoException("Error encrypting/decrypting file", ex); >> >
Both the methods encrypt() and decrypt() accepts a key, an input file and an output file as parameters, and throws a CryptoException which is a custom exception written as below:
package net.codejava.crypto; public class CryptoException extends Exception < public CryptoException() < >public CryptoException(String message, Throwable throwable) < super(message, throwable); >>
This custom exception eliminates the messy throws clause, thus make the caller invoking those methods without catching a lengthy list of original exceptions.
3. The CryptoUtilsTest class
The following code is written for a test class that tests the CryptoUtils class above:
package net.codejava.crypto; import java.io.File; /** * A tester for the CryptoUtils class. * @author www.codejava.net * */ public class CryptoUtilsTest < public static void main(String[] args) < String key = "Mary has one cat1"; File inputFile = new File("document.txt"); File encryptedFile = new File("document.encrypted"); File decryptedFile = new File("document.decrypted"); try < CryptoUtils.encrypt(key, inputFile, encryptedFile); CryptoUtils.decrypt(key, encryptedFile, decryptedFile); >catch (CryptoException ex) < System.out.println(ex.getMessage()); ex.printStackTrace(); >> >
This test program simply encrypts a text file, and then decrypts the encrypted file. Note that the key used for encryption and decryption here is a string “Mary has one cat”;
4. Note about key size
The AES algorithm requires that the key size must be 16 bytes (or 128 bit). So if you provide a key whose size is not equal to 16 bytes, a java.security.InvalidKeyException will be thrown. In case your key is longer, you should consider using a padding mechanism that transforms the key into a form in which its size is multiples of 16 bytes. See the Cipher class Javadoc for more details.
References:
Other Java Coding Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.
Add comment
Comments
finally worked, have to state permission about write external storage in the manifest, and created three files (document.txt, document.encrypted, document.decrypted) in the device. Note that write something into the document.txt file. And the string key is "Mary has one cat", NOT "Mary has one cat1".
Hi, I have used the logic to encrypt and decrypt my pdf file. It is working fine if encryption and decryption takes place in the same jvm. I am unable to decrypt the file on the other jvm even though I am using the same secret key and same code. Could you please guide me how to resolve the above issue.
iam having an error in file selected.
file is not found .what i have to do?plz reply as fast as possible
i am having this error ,what i should do?
"
Error encrypting/decrypting file
demoo.demo$CryptoException: Error encrypting/decrypting file
at demoo.demo.doCrypto(demo.java:69)
at demoo.demo.encrypt(demo.java:38)
at demoo.demo.main(demo.java:79)