gpt4 book ai didi

java - 如何用新加密的数据更新部分加密的数据?

转载 作者:行者123 更新时间:2023-12-02 11:57:21 27 4
gpt4 key购买 nike

我需要在生成音频文件时对其进行加密。我在开始时使用虚拟数据加密 header (因为我不知道音频数据的实际大小),并动态加密音频数据。我的计划是用音频文件的实际数据大小更新末尾的标题。

但是,当我尝试使用相同的 key 和 IV 用相同大小的新加密的 header 数据覆盖加密的 header 数据并稍后尝试解密时,我生成了垃圾数据。

即使我使用相同的 key 和 IV,为什么会发生这种情况?在下面的代码中,我尝试模拟我正在做的事情。生成大小为 64 字节的加密文件,生成大小为 50 字节的解密文件。

没有更新:abcdabcdab0123456789012345678901234567890123456789

header 更新:ABCDABCDAB÷´þ@óMCKLZfÖ^Ô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();
}
}

最佳答案

我建议您更新几件事:

  1. 您正在向同一个文件打开多个输出流,这很奇怪,运行时不应该允许您这样做。因此,如果您想要任何可预测的结果,请仅使用单个输出进行编写。

  2. 您可以阅读有关操作模式的信息,请参阅 CRT模式不使用填充,并允许您仅更新密文的一部分(假设您不使用经过身份验证的加密)。所以 AES/CTR/NoPadding 可以解决您的问题。 (如果你做得正确,就不应该有额外的字节)

  3. 您可以使用 RandomAccessFile 更新文件的一部分并覆盖密文中需要的部分。

关于java - 如何用新加密的数据更新部分加密的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47512224/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com