-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDecryptor.java
More file actions
85 lines (68 loc) · 3.1 KB
/
Decryptor.java
File metadata and controls
85 lines (68 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.nio.file.*;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;
public class Decryptor {
// ===== FOLDERS =====
static final Path ENCRYPTED_DIR = Paths.get("encrypted");
static final Path OUTPUT_DIR = Paths.get("output");
static final Path USER_KEYS = Paths.get("keys/User");
static final String USER_PRIVATE_KEY = "private.key";
// ===== CRYPTO CONSTANTS =====
static final int GCM_IV_SIZE = 12;
static final int GCM_TAG_SIZE = 128;
public static void main(String[] args) throws Exception {
Files.createDirectories(OUTPUT_DIR);
PrivateKey userPriv = loadPrivateKey(USER_KEYS.resolve(USER_PRIVATE_KEY));
Files.walk(ENCRYPTED_DIR)
.filter(p -> p.toString().endsWith(".enc"))
.forEach(encFile -> {
try {
decryptFile(encFile, userPriv);
System.out.println("✔ Decrypted: " + encFile);
} catch (Exception e) {
System.out.println("❌ Failed: " + encFile + " (" + e.getMessage() + ")");
}
});
System.out.println("Decryption complete. Exiting...");
}
static void decryptFile(Path encFile, PrivateKey rsaPriv) throws Exception {
Path keyFile = encFile.resolveSibling(encFile.getFileName() + ".key");
if (!Files.exists(keyFile))
throw new SecurityException("Missing key file: " + keyFile);
byte[] encKey = Files.readAllBytes(keyFile);
Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
rsa.init(Cipher.DECRYPT_MODE, rsaPriv);
byte[] aesBytes = rsa.doFinal(encKey);
SecretKey aesKey = new SecretKeySpec(aesBytes, "AES");
Path relative = ENCRYPTED_DIR.relativize(encFile);
Path outFile = OUTPUT_DIR.resolve(relative.toString().replace(".enc", ""));
Files.createDirectories(outFile.getParent());
try (DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(encFile)));
OutputStream out = Files.newOutputStream(outFile)) {
while (true) {
int len;
try {
len = in.readInt();
} catch (EOFException e) {
break; // finished
}
byte[] iv = in.readNBytes(GCM_IV_SIZE);
byte[] encrypted = in.readNBytes(len);
Cipher aes = Cipher.getInstance("AES/GCM/NoPadding");
aes.init(Cipher.DECRYPT_MODE, aesKey, new GCMParameterSpec(GCM_TAG_SIZE, iv));
byte[] plain = aes.doFinal(encrypted);
out.write(plain);
}
}
Files.delete(encFile);
Files.delete(keyFile);
}
static PrivateKey loadPrivateKey(Path path) throws Exception {
byte[] b = Base64.getDecoder().decode(Files.readAllBytes(path));
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(b));
}
}