[英]How to update part of the encrypted data with newly encrypted data?
在生成音頻文件時,我需要對其進行加密。 我在開始時使用偽數據(因為我不知道音頻數據的實際大小)對標頭進行加密,並即時對音頻數據進行加密。 我的計划是使用音頻文件的實際數據大小在末尾更新標頭。
但是,當我嘗試通過使用相同的密鑰和IV用相同大小的新加密頭數據覆蓋加密頭數據並稍后嘗試解密時,我得到的是垃圾數據。
即使我使用相同的鍵和IV,為什么會發生這種情況? 在下面的代碼中,我嘗試模擬自己在做什么。 生成大小為64字節的加密文件,並生成大小為50字節的解密文件。
不更新:abcdabcdab0123456789012345678901234567890123456789
帶有標頭更新:ABCDABCDAB÷‹þ@óMCKLZƒÖ^Ô234567890123456789
預期輸出:ABCDABCDAB0123456789012345678901234567890123456789
這是實現已加密數據的部分更新的正確方法嗎?
protected void Encrypt()
{
byte[] numBytes = {'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[] smallCase = {'a','b','c','d','a','b','c','d','a','b','c','d','a','b','c','d'};
byte[] capitalCase = {'A','B','C','D','A','B','C','D','A','B','C','D','A','B','C','D'};
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2withHmacSHA1And8BIT");
KeySpec spec = new PBEKeySpec("junglebook".toCharArray(), "Salt".getBytes(), 65536, 256);
SecretKey tmp = null;
tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
/* Encryption cipher initialization. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
Log.d("Encryption" + "iv data :", iv.toString());
/*Open two Cipher ouput streams to the same encrypted file*/
FileOutputStream os = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
CipherOutputStream cos = new CipherOutputStream(os,cipher);
FileOutputStream os1 = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.encrypted");
CipherOutputStream cos1 = new CipherOutputStream(os1,cipher);
int offset = 0;
Log.d("Encryption", "Writing cipher text to output file");
//Write 16 bytes header data with smallCase array
cos.write(smallCase, offset, 16);
// write 40 bytes actual data
cos.write(numBytes, 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);
}
cos.close();
// Overwrite header data with capitalCase array data
cos1.write(capitalCase, offset, 16);
cos1.close();
ivStream.close();
}catch (Exception e) {
e.printStackTrace();
}
}
protected void Decrypt()
{
byte[] dBytes = new byte[200];
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);
}
// Generate the secret key from same password and salt used in encryption
SecretKeyFactory dfactory = SecretKeyFactory.getInstance("PBKDF2withHmacSHA1And8BIT");
KeySpec dspec = new PBEKeySpec("junglebook".toCharArray(), "Salt".getBytes(), 65536, 256);
SecretKey dtmp = dfactory.generateSecret(dspec);
SecretKey dsecret = new SecretKeySpec(dtmp.getEncoded(), "AES");
// Initialize dcipher
Cipher dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
dcipher.init(Cipher.DECRYPT_MODE, dsecret, new IvParameterSpec(newivtext));
FileInputStream inputStream = new FileInputStream(sdCard.getAbsolutePath()+"/Notes/sample.encrypted");
CipherInputStream cis = new CipherInputStream(inputStream,dcipher);
FileOutputStream os = new FileOutputStream(sdCard.getAbsolutePath() + "/Notes/sample.decrypted");
int b = cis.read(dBytes);
while(b != -1) {
Log.d("Decryption","Bytes decrypted" + b);
os.write(dBytes, 0, b);
b = cis.read(dBytes);
}
cis.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
我建議您更新幾件事:
您正在打開多個輸出流到SAME文件,這很奇怪,運行時不應允許您這樣做。 因此-如果您想要任何可預測的結果,請僅使用單個輸出編寫。
您可能會讀到有關操作模式的信息,請參閱CRT模式不使用填充,並且只允許更新部分密文(假設您不使用經過身份驗證的加密)。 因此AES/CTR/NoPadding
可以解決您的問題。 (如果正確執行,則不應有多余的字節)
您可以使用RandomAccessFile更新文件的一部分,並覆蓋所需的密文部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.