I am trying to encrypt a file which consists of some sample data like
company=abc-company
I have written the following code to encrypt the file using AES-128
bit key using password and salt. I am able to encrypt the file successfully to a file and write the decrypted data from the file to another file successfully. But, I want to store the decrypted data in a string. So, after roaming here on SO, I used ByteArrayOutputStream
. But with that I am not able to get the complete plaintext in to the string. I am getting partial data (only first 16 characters ie excluding 'any') from the file. How to get the complete text from the file into the string?
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestAES {
private static final Logger logger = LoggerFactory.getLogger(TestAES.class);
private char[] password = "1111111111111111".toCharArray();
private byte[] salt = "SampleSalt".getBytes();
private byte[] initializationVector;
public static void main(String[] args) {
TestAES aes = new TestAES();
aes.encrypt(new File("D:\\plainText.licence"), new File("D:\\sample.licence"));
aes.decrypt(new File("D:\\sample.licence"));
}
public void encrypt(File plainTextFile, File encryptedLicenceFile) {
if (plainTextFile.exists() == false) {
try {
throw new FileNotFoundException("The plainTextFile was not found");
} catch (FileNotFoundException e) {
logger.error("The plainTextFile was not found", e);
e.printStackTrace();
}
}
if (encryptedLicenceFile.exists() == false) {
try {
encryptedLicenceFile.createNewFile();
} catch (IOException e) {
logger.error("IOException while creating encryptedLicenceFile", e);
e.printStackTrace();
}
}
logger.info("plainTextFile.exists() = " + plainTextFile.exists());
// To read the file to be encrypted
FileInputStream fileInputStream = null;
// To write the encrypted file
FileOutputStream fileOutputStream = null;
// To read the file information and to encrypt
CipherInputStream cipherInputStream = null;
try {
fileInputStream = new FileInputStream(plainTextFile);
fileOutputStream = new FileOutputStream(encryptedLicenceFile);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password, salt, 65536, 128);
logger.info("Generating KeySpec with password, salt.");
SecretKey secretKey = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
logger.debug("Obtaining AES cipher in encryption mode with secret key.");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters parameters = cipher.getParameters();
this.initializationVector = parameters.getParameterSpec(IvParameterSpec.class).getIV();
logger.info("Initialization Vector length = " + initializationVector.length);
cipherInputStream = new CipherInputStream(fileInputStream, cipher);
int read = 0;
while ((read = cipherInputStream.read()) != -1) {
fileOutputStream.write((char) read);
fileOutputStream.flush();
}
logger.info("Successfully written the sample.licence file.");
} catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException: Check alogrithm.", e);
e.printStackTrace();
} catch (NoSuchPaddingException e) {
logger.error("NoSuchPaddingException: Check padding.", e);
e.printStackTrace();
} catch (InvalidKeySpecException e) {
logger.error("InvalidKeySpecException: Check keySpec.", e);
e.printStackTrace();
} catch (InvalidKeyException e) {
logger.error("InvalidKeyException: Check keySize.", e);
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
logger.error("InvalidParameterSpecException: Check parameters.", e);
e.printStackTrace();
} catch (FileNotFoundException e) {
logger.error("FileNotFoundException: Check fileToBeEncrypted.", e);
e.printStackTrace();
} catch (IOException e) {
logger.error("IOException occured.", e);
e.printStackTrace();
} finally {
try {
if (cipherInputStream != null) {
cipherInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
logger.error("Exception while closing stream.", e);
e.printStackTrace();
}
}
}
public void decrypt(File sampleLicence) {
if (sampleLicence.exists() == false) {
try {
throw new FileNotFoundException("The sampleLicence was not found");
} catch (FileNotFoundException e) {
logger.error("The sampleLicence was not found", e);
e.printStackTrace();
}
}
// To read the sample.licence
FileInputStream fileInputStream = null;
// To write decrypted licence file
FileOutputStream fileOutputStream = null;
// To read encrypted licence file and decrypt it
CipherOutputStream cipherOutputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
fileInputStream = new FileInputStream(sampleLicence);
byteArrayOutputStream = new ByteArrayOutputStream();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password, salt, 65536, 128);
logger.info("Generating KeySpec with password, salt during decryption.");
SecretKey secretKey = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
logger.debug("Obtaining AES cipher in decryption mode with secret key.");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(initializationVector));
cipherOutputStream = new CipherOutputStream(byteArrayOutputStream, cipher);
byte[] data = new byte[4096];
int read;
while ((read = fileInputStream.read(data)) != -1) {
cipherOutputStream.write(data, 0, read);
}
cipherOutputStream.flush();
byte[] plainText = byteArrayOutputStream.toByteArray();
System.out.println(new String(plainText, "UTF-8"));
} catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException: Check alogrithm.", e);
e.printStackTrace();
} catch (NoSuchPaddingException e) {
logger.error("NoSuchPaddingException: Check padding.", e);
e.printStackTrace();
} catch (InvalidKeySpecException e) {
logger.error("InvalidKeySpecException: Check keySpec.", e);
e.printStackTrace();
} catch (InvalidKeyException e) {
logger.error("InvalidKeyException: Check keySize.", e);
e.printStackTrace();
} catch (FileNotFoundException e) {
logger.error("FileNotFoundException: Check fileToBeEncrypted.", e);
e.printStackTrace();
} catch (IOException e) {
logger.error("IOException occured.", e);
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
logger.error("InvalidAlgorithmParameterException", e);
e.printStackTrace();
} finally {
try {
if (cipherOutputStream != null) {
cipherOutputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
} catch (IOException e) {
logger.error("Exception while closing stream.", e);
e.printStackTrace();
}
}
}
}
I did not try that, but it looks like you need to close the cipherOutputStream
:
cipherOutputStream.close();
instead of the flush you have currently.
The reason is that flush
can be called several times so the decryption will not be finished until close
is called.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.