文件夾是邏輯概念,**加密實質是遍歷文件逐個加密**,保持目錄結構不變。
public class FolderEncryptor {
private final Cipher cipher;
private final byte[] iv; // 16 字節 for AES/CBC
public FolderEncryptor(String password) throws Exception {
// PBKDF2 派生密鑰
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password.toCharArray(), SALT, 65536, 256);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
iv = new byte[16];
new SecureRandom().nextBytes(iv);
}
public void encryptFolder(File srcDir, File destDir) throws IOException {
Files.walkFileTree(srcDir.toPath(), new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path rel = srcDir.toPath().relativize(file);
File outFile = destDir.toPath().resolve(rel + ".enc").toFile();
outFile.getParentFile().mkdirs();
encryptFile(file.toFile(), outFile);
return FileVisitResult.CONTINUE;
}
});
// 保存 IV 到 destDir/.iv 供解密使用
Files.write(destDir.toPath().resolve(".iv"), iv);
}
private void encryptFile(File in, File out) throws IOException {
try (FileInputStream fis = new FileInputStream(in);
FileOutputStream fos = new FileOutputStream(out);
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
byte[] buf = new byte[8192];
int n;
while ((n = fis.read(buf)) != -1) cos.write(buf, 0, n);
}
}
// 解密對稱,Cipher.DECRYPT_MODE,讀取 .iv 恢復 IV
}
CipherInputStream/OutputStream 避免大文件載入內存
src/
a.txt
sub/
b.jpg
dest/
a.txt.enc
sub/
b.jpg.enc
.iv (16 字節)