我正在研究一个用于加密/解密大文件的类,因此我试图使用流而不是字节数组来避免OutOfMemory异常。
在加密方法中,我将随机salt和iv添加到加密文件的开头,并且工作正常,这是代码:
public File encryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage){ //Create IV byte[] ivBytes = new byte[16]; SecureRandom random1 = new SecureRandom(); random1.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); //Create the key with the salt SecureRandom random = new SecureRandom(); byte[] salt = new byte[SALT_SIZE]; random.nextBytes(salt); SecretKeySpec keySpec = generateAesKey(password, salt); //Create and Init the cipher Cipher c = Cipher.getInstance("AES/CBC/"+padding); c.init(Cipher.ENCRYPT_MODE, keySpec, iv); byte[] buf = new byte[8192]; FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outPutFile); int nread; int progress = 0; byte[] ivAndSalt = new byte[ivBytes.length + salt.length]; System.arraycopy(ivBytes,0, ivAndSalt,0, ivBytes.length ); System.arraycopy(salt, 0, ivAndSalt, ivBytes.length, salt.length); out.write(ivAndSalt); while((nread = in.read(buf)) != -1) { byte[] enc = c.update(buf, 0, nread); out.write(enc); progress++; }
然后我尝试使用解密方法获得iv和salt,然后使用FileInputStream.getChannel.position()
将文件的其余部分解密为输出文件:
public File decryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage) { //Create and Init Cipher Cipher c = Cipher.getInstance("AES/CBC/" + padding); FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outPutFile); //Getting the iv and salt byte[] ivBytes = new byte[16]; byte[] salt = new byte[SALT_SIZE]; byte[] ivAndSalt = new byte[ivBytes.length+SALT_SIZE]; in.read(ivAndSalt, 0, ivBytes.length+SALT_SIZE); System.arraycopy(ivAndSalt, 0, ivBytes, 0, ivBytes.length); System.arraycopy(ivAndSalt, ivBytes.length, salt, 0, SALT_SIZE); IvParameterSpec iv =new IvParameterSpec(ivBytes); SecretKeySpec keySpec = generateAesKey(password, salt); c.init(Cipher.DECRYPT_MODE, keySpec, iv); in.getChannel().position(ivAndSalt.length); int nread; int progress = 0; byte[] buf = new byte[8192]; while((nread = in.read(buf)) != -1) { byte[] enc = c.update(buf, 0, nread); out.write(enc); progress++; /*if (enc.length / 8192 != 0) System.out.println((nread*progress) + "%");*/ } System.out.println("Size of out before doFinal(): " + out.getChannel().size()); byte[] enc = c.doFinal(); out.write(enc); System.out.println("Size of out after doFinal(): " + out.getChannel().size()); return outPutFile; }
我在调用cryptoFile()时没有出错,但是生成的文件已损坏,这意味着解密中存在问题。
答案 0 :(得分:0)
问题完全是愚蠢的,我忘记在doFinal()
之后关闭输入和输出流,并将enc字节数组写入输出:
in.close();
out.close();