我有一个可以将给定文件拆分并合并为多个文件的类,但是我想知道如何在拆分时加密每个文件,然后在再次合并时解密。
这是文件拆分和合并的类。
public void splitFile(File f) throws Exception {
int partCounter = 1;
int sizeOfFiles = (int) (f.length() / 3);
byte[] buffer = new byte[sizeOfFiles];
String fileName = f.getName();
String destFileName = fileName.substring(0, fileName.lastIndexOf('.')) + "." + FilenameUtils.getExtension(fileName);
try (FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis)) {
int bytesAmount = 0;
while ((bytesAmount = bis.read(buffer)) > 0) {
String filePartName = String.format("%s.%03d", destFileName, partCounter++);
File newFile = new File("D:\\FileTest\\", filePartName);
try (FileOutputStream out = new FileOutputStream(newFile)) {
//I think this is how you encrypt each split part before it gets written to a file?
out.write(FileEncrypt.encrypt(buffer, encKey), 0, bytesAmount);
}
}
bos.close();
}
}
public List<File> listOfFilesToMerge(File oneOfFiles) throws IOException, Exception {
String tmpName = oneOfFiles.getName();
String destFileName = tmpName.substring(0, tmpName.lastIndexOf('.'));
File[] files = oneOfFiles.getParentFile().listFiles((File dir, String name) -> name.matches(destFileName + "[.]\\d+"));
Arrays.sort(files);
for (File f : files) {
//And this is how to decrypt the files before it gets merged?
FileEncrypt.decrypt(Files.readAllBytes(f.toPath()), encKey);
}
return Arrays.asList(files);
}
public void mergeFiles(List<File> files, File into) throws Exception {
try (FileOutputStream fos = new FileOutputStream(into);
BufferedOutputStream mergingStream = new BufferedOutputStream(fos)) {
for (File f : files) {
Files.copy(f.toPath(), mergingStream);
}
}
}
这是加密类。
public static byte[] encrypt(byte[] bytes, String key) throws Exception {
byte[] iv = new byte[ivSize];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(key.getBytes("UTF-8"));
byte[] keyBytes = new byte[keySize];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(bytes);
byte[] encryptedIVAndFile = new byte[ivSize + encrypted.length];
System.arraycopy(iv, 0, encryptedIVAndFile, 0, ivSize);
System.arraycopy(encrypted, 0, encryptedIVAndFile, ivSize, encrypted.length);
return encryptedIVAndFile;
}
public static byte[] decrypt(byte[] encryptedIvFileBytes, String key) throws Exception {
byte[] iv = new byte[ivSize];
System.arraycopy(encryptedIvFileBytes, 0, iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
int encryptedSize = encryptedIvFileBytes.length - ivSize;
byte[] encryptedBytes = new byte[encryptedSize];
System.arraycopy(encryptedIvFileBytes, ivSize, encryptedBytes, 0, encryptedSize);
byte[] keyBytes = new byte[keySize];
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes("UTF-8"));
System.arraycopy(md.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes);
return decrypted;
}
public static String generateEncKey() {
int strLen = 16;
char[] chars = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < strLen; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
return sb.toString();
}
运行代码时,出现以下错误-javax.crypto.BadPaddingException:给定最后一个块,未正确填充。如果在解密过程中使用了错误的密钥,则会出现此类问题。
但是,我可以加密和解密文件而无需拆分和合并。
所以我想知道我无法加密每个分割部分然后解密的代码有什么问题。