在此示例中,我尝试使用CipherOutputStream加密音频文件头和数据。我将相应的IV1存储到文件中 后来,我加密了更新的标头并覆盖了以前的密码数据。我将相应的IV2存储到文件中。
我觉得写入文件的IV1将不再有用,因为我覆盖了第一个标头密码数据。
在解密方面,通过使用IV2,我只能解密更新的标题部分 即使我使用IV1,我也无法解密实际数据。这也很有道理。因为,使用IV1加密的数据已被覆盖。
如何解密此方案中的数据?还是我完全错了?请帮帮忙?
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();
}
}