In this example, I am trying to encrypt audio file header and data using CipherOutputStream. I stored the corresponding IV1 to file.
Later, I encrypted the updated header and overwrote the previous cipher data. I stored the corresponding IV2 to file.
I feel the IV1 written to file will no longer useful, because I overwritten the first header cipher data.
On decryption side, by using IV2 I am able to decrypt updated header part only.
I am unable to decrypt the actual data even though I used IV1. It makes sense also. Because, the data that is encrypted using IV1 has been overwritten.
How can I decrypt the data in this scenario? Or am I going completely wrong? Please help?
protected void EncryptAndroid()
{
byte[] data = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
byte[] header = {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd',
'a', 'b', 'c', 'd',};
byte[] updatedHeader = {'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D',
'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D'};
try {
SecretKey secret = generateKeyAndroid();
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
FileOutputStream os = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
CipherOutputStream cos = new CipherOutputStream(os, cipher);
int offset = 0;
cos.write(header, offset, 10);
cos.write(data, offset, 40);
FileOutputStream ivStream = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/iv.dat");
if (ivStream != null) {
Log.d("Encryption", "Writing iv data to output file");
ivStream.write(iv);
}
ivStream.close();
cos.close();
//Create new instance of cipher
cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params1 = cipher.getParameters();
byte[] iv1 = params1.getParameterSpec(IvParameterSpec.class).getIV();
//Re open the file to Update the header at starting of the file.
FileOutputStream os1 = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
CipherOutputStream cos1 = new CipherOutputStream(os1, cipher);
cos1.write(updatedHeader, offset, 10);
cos1.close();
FileOutputStream ivStream1 = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/iv1.dat");
if (ivStream1 != null) {
Log.d("Encryption", "Writing iv data to output file");
ivStream1.write(iv1);
}
}catch (Exception e) {
e.printStackTrace();
}
}
protected void DecryptAndroid() {
byte[] hBytes = new byte[10];
byte[] dBytes = new byte[100];
try {
Log.d("Decryption", "Reading iv data ");
File f1 = new File(sdCard.getAbsolutePath() + "/Notes/iv.dat");
byte[] newivtext = new byte[(int) f1.length()];
FileInputStream readivStream = new FileInputStream(sdCard.getAbsolutePath() + "/Notes/iv.dat");
if (readivStream != null) {
readivStream.read(newivtext);
}
File f2 = new File(sdCard.getAbsolutePath() + "/Notes/iv1.dat");
byte[] newivtext1 = new byte[(int) f2.length()];
FileInputStream readivStream1 = new FileInputStream(sdCard.getAbsolutePath() + "/Notes/iv1.dat");
if (readivStream1 != null) {
readivStream1.read(newivtext1);
}
// The key can also be obtained from the Android Keystore any time as follows:
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey dsecret = (SecretKey) keyStore.getKey("key2", null);
// Initialize dcipher
Cipher dcipher = Cipher.getInstance("AES/CTR/NoPadding");
dcipher.init(Cipher.DECRYPT_MODE, dsecret,new IvParameterSpec(newivtext1));
FileInputStream inputStream = new FileInputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
FileOutputStream os = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.decrypted");
//decrypt header
int b = inputStream.read(hBytes);
byte[] dB = new byte[10];
dB = dcipher.doFinal(hBytes);
os.write(dB, 0, b);
// Re-Initialize dcipher
dcipher = Cipher.getInstance("AES/CTR/NoPadding");
dcipher.init(Cipher.DECRYPT_MODE, dsecret,new IvParameterSpec(newivtext));
FileInputStream inputStream1 = new FileInputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
inputStream1.skip(10);
CipherInputStream cis = new CipherInputStream(inputStream1, dcipher);
b = cis.read(dBytes);
while (b != -1) {
Log.d("Decryption", "Bytes decrypted" + b);
os.write(dBytes, 0, b);
}
cis.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
See Question&Answers more detail:
os