Skip to content

Commit edd6154

Browse files
committed
Initial Code Commit
1 parent d3f4b65 commit edd6154

File tree

17 files changed

+685
-0
lines changed

17 files changed

+685
-0
lines changed

pom.xml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.securefilevault</groupId>
8+
<artifactId>secure-file-vault</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
<maven.compiler.source>20</maven.compiler.source>
14+
<maven.compiler.target>20</maven.compiler.target>
15+
<javafx.version>24</javafx.version>
16+
</properties>
17+
18+
<dependencies>
19+
<!-- JavaFX -->
20+
<dependency>
21+
<groupId>org.openjfx</groupId>
22+
<artifactId>javafx-controls</artifactId>
23+
<version>${javafx.version}</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.openjfx</groupId>
27+
<artifactId>javafx-fxml</artifactId>
28+
<version>${javafx.version}</version>
29+
</dependency>
30+
31+
<!-- SQLite -->
32+
<dependency>
33+
<groupId>org.xerial</groupId>
34+
<artifactId>sqlite-jdbc</artifactId>
35+
<version>3.49.1.0</version>
36+
</dependency>
37+
38+
<!-- Apache Commons -->
39+
<dependency>
40+
<groupId>org.apache.commons</groupId>
41+
<artifactId>commons-lang3</artifactId>
42+
<version>3.14.0</version>
43+
</dependency>
44+
45+
<!-- JUnit for testing -->
46+
<dependency>
47+
<groupId>org.junit.jupiter</groupId>
48+
<artifactId>junit-jupiter</artifactId>
49+
<version>5.10.2</version>
50+
<scope>test</scope>
51+
</dependency>
52+
</dependencies>
53+
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>org.apache.maven.plugins</groupId>
58+
<artifactId>maven-compiler-plugin</artifactId>
59+
<version>3.11.0</version>
60+
<configuration>
61+
<source>${maven.compiler.source}</source>
62+
<target>${maven.compiler.target}</target>
63+
</configuration>
64+
</plugin>
65+
<plugin>
66+
<groupId>org.openjfx</groupId>
67+
<artifactId>javafx-maven-plugin</artifactId>
68+
<version>0.0.8</version>
69+
<configuration>
70+
<mainClass>com.securefilevault.Main</mainClass>
71+
</configuration>
72+
</plugin>
73+
</plugins>
74+
</build>
75+
</project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.securefilevault;
2+
3+
import javafx.application.Application;
4+
import javafx.fxml.FXMLLoader;
5+
import javafx.scene.Parent;
6+
import javafx.scene.Scene;
7+
import javafx.stage.Stage;
8+
9+
public class Main extends Application {
10+
@Override
11+
public void start(Stage primaryStage) throws Exception {
12+
Parent root = FXMLLoader.load(getClass().getResource("/fxml/login.fxml"));
13+
primaryStage.setTitle("Secure File Vault");
14+
primaryStage.setScene(new Scene(root, 800, 600));
15+
primaryStage.show();
16+
}
17+
18+
public static void main(String[] args) {
19+
launch(args);
20+
}
21+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.securefilevault.controllers;
2+
3+
import javafx.fxml.FXML;
4+
import javafx.fxml.FXMLLoader;
5+
import javafx.scene.Parent;
6+
import javafx.scene.Scene;
7+
import javafx.scene.control.*;
8+
import javafx.stage.Stage;
9+
import com.securefilevault.services.AuthService;
10+
import com.securefilevault.services.DatabaseService;
11+
12+
import java.io.IOException;
13+
14+
public class LoginController {
15+
@FXML private TextField usernameField;
16+
@FXML private PasswordField passwordField;
17+
@FXML private Button loginButton;
18+
@FXML private Hyperlink registerLink;
19+
@FXML private Label errorLabel;
20+
21+
private final AuthService authService;
22+
private final DatabaseService databaseService;
23+
24+
public LoginController() {
25+
this.databaseService = new DatabaseService();
26+
this.authService = new AuthService(databaseService);
27+
}
28+
29+
@FXML
30+
public void initialize() {
31+
loginButton.setOnAction(event -> handleLogin());
32+
registerLink.setOnAction(event -> handleRegister());
33+
}
34+
35+
private void handleLogin() {
36+
String username = usernameField.getText();
37+
String password = passwordField.getText();
38+
39+
if (username.isEmpty() || password.isEmpty()) {
40+
errorLabel.setText("Please enter both username and password");
41+
return;
42+
}
43+
44+
try {
45+
if (authService.authenticate(username, password)) {
46+
loadMainView();
47+
} else {
48+
errorLabel.setText("Invalid username or password");
49+
}
50+
} catch (Exception e) {
51+
errorLabel.setText("An error occurred during login");
52+
e.printStackTrace();
53+
}
54+
}
55+
56+
private void handleRegister() {
57+
try {
58+
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/register.fxml"));
59+
Parent root = loader.load();
60+
Stage stage = (Stage) registerLink.getScene().getWindow();
61+
stage.setScene(new Scene(root));
62+
} catch (IOException e) {
63+
errorLabel.setText("Failed to load registration screen");
64+
e.printStackTrace();
65+
}
66+
}
67+
68+
private void loadMainView() {
69+
try {
70+
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"));
71+
Parent root = loader.load();
72+
Stage stage = (Stage) loginButton.getScene().getWindow();
73+
stage.setScene(new Scene(root));
74+
} catch (IOException e) {
75+
errorLabel.setText("Failed to load main view");
76+
e.printStackTrace();
77+
}
78+
}
79+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package com.securefilevault.controllers;
2+
3+
import javafx.fxml.FXML;
4+
import javafx.fxml.FXMLLoader;
5+
import javafx.scene.Parent;
6+
import javafx.scene.Scene;
7+
import javafx.scene.control.*;
8+
import javafx.stage.FileChooser;
9+
import javafx.stage.Stage;
10+
import com.securefilevault.services.EncryptionService;
11+
import com.securefilevault.services.DatabaseService;
12+
13+
import java.io.File;
14+
import java.io.IOException;
15+
import java.util.List;
16+
17+
public class MainController {
18+
@FXML private Label welcomeLabel;
19+
@FXML private Button logoutButton;
20+
@FXML private Button encryptButton;
21+
@FXML private Button decryptButton;
22+
@FXML private ListView<String> fileListView;
23+
@FXML private Label statusLabel;
24+
25+
private final EncryptionService encryptionService;
26+
private final DatabaseService databaseService;
27+
private String currentUsername;
28+
29+
public MainController() {
30+
this.encryptionService = new EncryptionService();
31+
this.databaseService = new DatabaseService();
32+
}
33+
34+
@FXML
35+
public void initialize() {
36+
setupEventHandlers();
37+
}
38+
39+
public void setUsername(String username) {
40+
this.currentUsername = username;
41+
welcomeLabel.setText("Welcome, " + username + "!");
42+
}
43+
44+
private void setupEventHandlers() {
45+
logoutButton.setOnAction(event -> handleLogout());
46+
encryptButton.setOnAction(event -> handleEncrypt());
47+
decryptButton.setOnAction(event -> handleDecrypt());
48+
}
49+
50+
private void handleLogout() {
51+
try {
52+
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/login.fxml"));
53+
Parent root = loader.load();
54+
Stage stage = (Stage) logoutButton.getScene().getWindow();
55+
stage.setScene(new Scene(root));
56+
} catch (IOException e) {
57+
statusLabel.setText("Failed to logout");
58+
e.printStackTrace();
59+
}
60+
}
61+
62+
private void handleEncrypt() {
63+
FileChooser fileChooser = new FileChooser();
64+
fileChooser.setTitle("Select File to Encrypt");
65+
File selectedFile = fileChooser.showOpenDialog(encryptButton.getScene().getWindow());
66+
67+
if (selectedFile != null) {
68+
try {
69+
String password = showPasswordDialog("Enter encryption password:");
70+
if (password != null) {
71+
File encryptedFile = new File(selectedFile.getAbsolutePath() + ".encrypted");
72+
encryptionService.encryptFile(selectedFile, encryptedFile, password);
73+
fileListView.getItems().add(encryptedFile.getName());
74+
statusLabel.setText("File encrypted successfully: " + encryptedFile.getName());
75+
}
76+
} catch (Exception e) {
77+
statusLabel.setText("Encryption failed: " + e.getMessage());
78+
e.printStackTrace();
79+
}
80+
}
81+
}
82+
83+
private void handleDecrypt() {
84+
FileChooser fileChooser = new FileChooser();
85+
fileChooser.setTitle("Select File to Decrypt");
86+
File selectedFile = fileChooser.showOpenDialog(decryptButton.getScene().getWindow());
87+
88+
if (selectedFile != null) {
89+
try {
90+
String password = showPasswordDialog("Enter decryption password:");
91+
if (password != null) {
92+
String outputPath = selectedFile.getAbsolutePath().replace(".encrypted", "");
93+
File decryptedFile = new File(outputPath);
94+
encryptionService.decryptFile(selectedFile, decryptedFile, password);
95+
fileListView.getItems().add(decryptedFile.getName());
96+
statusLabel.setText("File decrypted successfully: " + decryptedFile.getName());
97+
}
98+
} catch (Exception e) {
99+
statusLabel.setText("Decryption failed: " + e.getMessage());
100+
e.printStackTrace();
101+
}
102+
}
103+
}
104+
105+
private String showPasswordDialog(String message) {
106+
Dialog<String> dialog = new Dialog<>();
107+
dialog.setTitle("Password Required");
108+
dialog.setHeaderText(message);
109+
110+
PasswordField passwordField = new PasswordField();
111+
dialog.getDialogPane().setContent(passwordField);
112+
113+
ButtonType okButton = new ButtonType("OK", ButtonBar.ButtonData.OK_DONE);
114+
dialog.getDialogPane().getButtonTypes().addAll(okButton, ButtonType.CANCEL);
115+
116+
dialog.setResultConverter(dialogButton -> {
117+
if (dialogButton == okButton) {
118+
return passwordField.getText();
119+
}
120+
return null;
121+
});
122+
123+
return dialog.showAndWait().orElse(null);
124+
}
125+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.securefilevault.services;
2+
3+
import javax.crypto.SecretKeyFactory;
4+
import javax.crypto.spec.PBEKeySpec;
5+
import java.security.NoSuchAlgorithmException;
6+
import java.security.spec.InvalidKeySpecException;
7+
import java.security.spec.KeySpec;
8+
import java.util.Base64;
9+
10+
public class AuthService {
11+
private static final int ITERATIONS = 65536;
12+
private static final int KEY_LENGTH = 256;
13+
private static final String ALGORITHM = "PBKDF2WithHmacSHA256";
14+
15+
private final DatabaseService databaseService;
16+
17+
public AuthService(DatabaseService databaseService) {
18+
this.databaseService = databaseService;
19+
}
20+
21+
public boolean authenticate(String username, String password) {
22+
try {
23+
String storedHash = databaseService.getUserPasswordHash(username);
24+
if (storedHash == null) {
25+
return false;
26+
}
27+
28+
String[] parts = storedHash.split(":");
29+
byte[] salt = Base64.getDecoder().decode(parts[0]);
30+
String hash = parts[1];
31+
32+
String computedHash = hashPassword(password, salt);
33+
return hash.equals(computedHash);
34+
} catch (Exception e) {
35+
e.printStackTrace();
36+
return false;
37+
}
38+
}
39+
40+
public String hashPassword(String password, byte[] salt) {
41+
try {
42+
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
43+
SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
44+
byte[] hash = factory.generateSecret(spec).getEncoded();
45+
return Base64.getEncoder().encodeToString(hash);
46+
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
47+
throw new RuntimeException("Error hashing password", e);
48+
}
49+
}
50+
51+
public byte[] generateSalt() {
52+
java.security.SecureRandom random = new java.security.SecureRandom();
53+
byte[] salt = new byte[16];
54+
random.nextBytes(salt);
55+
return salt;
56+
}
57+
}

0 commit comments

Comments
 (0)