You are on page 1of 21

Module Title: Network & Security Programming

Module Code: ITNW4115


Method of Assessment: Project

Project Title
Create in JAVA a secure file sharing system
Introduction
In today's digital age, file sharing has become an essential part of our personal and
professional lives. However, the sharing of sensitive documents and data can pose
significant security risks if not handled carefully. Therefore, the development of a
secure file sharing system is crucial to ensure that data is protected from
unauthorized access and data breaches.
A secure file sharing system is a software application that enables users to share
files securely while ensuring that the data remains confidential and cannot be
accessed or tampered with by unauthorized parties. The system is designed with
various security features such as authentication, encryption, and secure
communication protocols to ensure that data is not susceptible to unauthorized
access or data breaches.
The primary objective of a secure file sharing system is to provide authorized users
with secure access to files while ensuring that the data remains confidential and
secure from unauthorized access. The system is particularly useful for sharing
sensitive documents, data, and other confidential information that must be
protected from unauthorized access.
In this project, we will develop a secure file sharing system using Java's security
packages such as Java Cryptography Architecture (JCA) and Java Cryptography
Extension (JCE). The system will be designed with various security features to
ensure that it is secure and efficient. The authentication feature will require users to
authenticate themselves before accessing any files, while the encryption feature
will ensure that all files are encrypted before they are stored on the server.
Additionally, the system will use secure communication protocols such as
SSL/TLS to encrypt all communication between the client and server.
Overall,the secure file sharing system we will develop in this project will provide a
secure and efficient way for users to share sensitive documents, data, and other
confidential information while protecting against unauthorized access and data
breaches.
Abstract
The main objective of this project is to create a file sharing system that is both
secure and efficient. The system will have various features such as authentication,
encryption, and secure communication protocols. These features will ensure that
the system is secure from unauthorized access and data tampering.
The authentication feature requires users to authenticate themselves before
accessing any files. Users will have to provide their username and password or
other secure means to access the system.
The encryption feature will ensure that all files are encrypted before they are stored
on the server. This will prevent unauthorized access to the files and ensure that data
is secure.
The secure communication feature will use protocols such as SSL/TLS to encrypt
all communication between the client and server. This will ensure that all data
transmitted between the client and server is secure and cannot be intercepted by
unauthorized parties.
Overall, the project aims to create a secure file sharing system that can be used for
various purposes such as sharing sensitive documents, data, and other confidential
information.
Theoretical Study
To create a secure file sharing system using Java security packages, it is essential
to understand the underlying theoretical concepts and principles that enable secure
file sharing. These concepts are critical to the development of a secure file sharing
system that ensures the confidentiality, integrity, and availability of shared data.
Authentication
Authentication is the process of verifying the identity of a user before granting
access to the system. In a secure file sharing system, authentication is necessary to
ensure that only authorized users can access the shared data. The system should
require users to authenticate themselves before accessing any files. This can be
achieved through various means such as passwords, biometric authentication, and
two-factor authentication.

Encryption
Encryption is the process of converting data into an unreadable format that can
only be decrypted by authorized users with the right decryption key. In a secure file
sharing system, encryption is essential to protect data from unauthorized access by
converting the data into an unreadable format. The system should encrypt files
before they are stored on the server, and decrypt them when they are requested by
authenticated users. Encryption can be achieved through various encryption
algorithms, such as AES, Blowfish, and RSA.
Secure Communication
Secure communication protocols such as SSL/TLS are essential for ensuring that
all communication between the client and server is encrypted. SSL/TLS provides
a secure communication channel between the client and server by encrypting the
data transmitted between them. This ensures that data transmitted between the
client and server is secure and cannot be intercepted by unauthorized parties.
SSL/TLS uses various cryptographic protocols such as Public Key
Infrastructure(PKI), digital certificates, and symmetric encryption algorithms to
ensure secure communication.
Public Key Infrastructure (PKI) is a set of technologies and techniques used to
manage digital certificates and public-key encryption. PKI enables secure
communication by providing a trusted third-party authority that issues digital
certificates to authenticate users and devices. Digital certificates are used to verify
the identity of a user or device and ensure that the communication is encrypted
using the correct encryption algorithm.
Symmetric encryption algorithms such as Advanced Encryption Standard (AES)
and Blowfish are used to encrypt and decrypt data in a secure file sharing system.
These algorithms use a single key that is shared between the sender and receiver to
encrypt and decrypt data. The key is kept secret to ensure that only authorized
users can access the data.
In addition to these concepts, it is essential to understand the principles of secure
programming to develop a secure file sharing system. Secure programming
involves designing and implementing software applications that are resistant to
security threats such as hacking, malware, and data breaches. It involves
using secure coding practices, such as input validation, error handling, and access
control, to prevent security vulnerabilities in the software.
In conclusion, a secure file sharing system requires a combination of
authentication, encryption, and secure communication protocols to ensure the
confidentiality, integrity, and availability of shared data. These concepts must be
implemented using secure programming practices to develop a system that is
resistant to security threats and provides a secure and efficient way to share
sensitive data. The Java Cryptography Architecture (JCA)and Java Cryptography
Extension (JCE) provide a range of cryptographic tools and techniques that can be
used to implement these concepts and ensure the security of a file sharing system.
By understanding and applying these theoretical concepts and principles,
developers can create a secure file sharing system that meets the needs of users
while protecting against unauthorized access and data breaches.
Code of Server
package securefilesharingsystemserver;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.net.ssl.*;
import java.util.*;

public class SecureFileSharingSystemServer {

private static final String KEYSTORE_LOCATION = "mykeystoreR.jks";


private static final String KEYSTORE_PASSWORD = "P@ssw0rd";
private static final String TRUSTSTORE_LOCATION = "mytruststoreR.jks";
private static final String TRUSTSTORE_PASSWORD = "P@ssw0rd";
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String KEY_ALGORITHM = "AES";
private static final int KEY_SIZE = 128;
private static final String[] USERS = {"user1", "user2", "user3"};
private static final String[] PASSWORDS = {"password1", "password2",
"password3"};
private static final String FILE_DIRECTORY = "files/";
public static void main(String[] args) throws Exception {
SSLServerSocketFactory sslServerSocketFactory =
createSSLServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket)
sslServerSocketFactory.createServerSocket(8000);
System.out.println("The Server started on port 8000");

while (true) {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
System.out.println("THe Client connected: " +
sslSocket.getInetAddress().getHostName());

BufferedReader in = new BufferedReader(new


InputStreamReader(sslSocket.getInputStream()));
PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);

String username = in.readLine();


String password = in.readLine();

if (authenticate(username, password)) {
out.println("Authenticated");

String filename = in.readLine();


String mode = in.readLine();

if (mode.equals("upload")) {
receiveFile(sslSocket, filename);
} else if (mode.equals("download")) {
sendFile(sslSocket, filename);
}
} else {
out.println("Authentication failed");
}

sslSocket.close();
}
}

private static SSLServerSocketFactory createSSLServerSocketFactory() throws


Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(KEYSTORE_LOCATION),
KEYSTORE_PASSWORD.toCharArray());

KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore,
KEYSTORE_PASSWORD.toCharArray());

KeyStore trustStore = KeyStore.getInstance("JKS");


trustStore.load(new FileInputStream(TRUSTSTORE_LOCATION),
TRUSTSTORE_PASSWORD.toCharArray());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLS");


sslContext.init(keyManagerFactory.getKeyManagers(),
trustManagerFactory.getTrustManagers(), new SecureRandom());

return sslContext.getServerSocketFactory();
}

private static boolean authenticate(String username, String password) {


for (int i = 0; i < USERS.length; i++) {
if (username.equals(USERS[i]) && password.equals(PASSWORDS[i])) {
return true;
}
}
return false;
}

private static void receiveFile(SSLSocket sslSocket, String filename) throws


Exception {
InputStream inputStream = sslSocket.getInputStream();
Cipher cipher = createCipher(Cipher.DECRYPT_MODE);

FileOutputStream fileOutputStream = new


FileOutputStream(FILE_DIRECTORY + filename);
byte[] buffer = new byte[1024];
int bytesRead;

while ((bytesRead = inputStream.read(buffer)) != -1) {


byte[] decryptedBytes = cipher.update(buffer, 0, bytesRead);
fileOutputStream.write(decryptedBytes);
}

byte[] decryptedBytes = cipher.doFinal();


fileOutputStream.write(decryptedBytes);

fileOutputStream.close();
}

private static void sendFile(SSLSocket sslSocket, String filename) throws


Exception {
OutputStream outputStream = sslSocket.getOutputStream();
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE);

FileInputStream fileInputStream = new FileInputStream(FILE_DIRECTORY


+ filename);
byte[] buffer = new byte[124];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
byte[] encryptedBytes = cipher.update(buffer, 0, bytesRead);
outputStream.write(encryptedBytes);
}

byte[] encryptedBytes = cipher.doFinal();


outputStream.write(encryptedBytes);

fileInputStream.close();
}

private static Cipher createCipher(int mode) throws Exception {


KeyGenerator keyGenerator =
KeyGenerator.getInstance(KEY_ALGORITHM);
keyGenerator.init(KEY_SIZE);
SecretKey secretKey = keyGenerator.generateKey();

Cipher cipher = Cipher.getInstance(ALGORITHM);


byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

cipher.init(mode, secretKey, ivParameterSpec);

return cipher;
}
}
Code of Client
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to
change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this
template
*/
package securefilesharingsystemclient;
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.net.ssl.*;
import java.util.*;

public class SecureFileSharingSystemClient {

private static final String KEYSTORE_LOCATION = "keystore.jks";


private static final String KEYSTORE_PASSWORD = "P@ssw0rd";
private static final String TRUSTSTORE_LOCATION = "truststore.jks";
private static final String TRUSTSTORE_PASSWORD = "P@ssw0rd";
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String KEY_ALGORITHM = "AES";
private static final int KEY_SIZE = 128;
private static final String SERVER_HOSTNAME = "localhost";
private static final int SERVER_PORT = 8000;

public static void main(String[] args) throws Exception {


SSLContext sslContext = createSSLContext();
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslSocket = (SSLSocket)
sslSocketFactory.createSocket(SERVER_HOSTNAME, SERVER_PORT);
System.out.println("Connected to server");

BufferedReader in = new BufferedReader(new


InputStreamReader(sslSocket.getInputStream()));
PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);

Scanner scanner = new Scanner(System.in);


System.out.print("Username: ");
String username = scanner.nextLine();
System.out.print("Password: ");
String password = scanner.nextLine();

out.println(username);
out.println(password);

String response = in.readLine();


if (response.equals("Authenticated")) {
System.out.print("Enter filename: ");
String filename = scanner.nextLine();
System.out.print("Enter mode (upload/download): ");
String mode = scanner.nextLine();

out.println(filename);
out.println(mode);

if (mode.equals("upload")) {
sendFile(sslSocket, filename);
} else if (mode.equals("download")) {
receiveFile(sslSocket, filename);
}
} else {
System.out.println("Authentication failed");
}

sslSocket.close();
}

private static SSLContext createSSLContext() throws Exception {


KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(KEYSTORE_LOCATION),
KEYSTORE_PASSWORD.toCharArray());

KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore,
KEYSTORE_PASSWORD.toCharArray());

KeyStore trustStore = KeyStore.getInstance("JKS");


trustStore.load(new FileInputStream(TRUSTSTORE_LOCATION),
TRUSTSTORE_PASSWORD.toCharArray());

TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLS");


sslContext.init(keyManagerFactory.getKeyManagers(),
trustManagerFactory.getTrustManagers(), new SecureRandom());

return sslContext;
}

private static void sendFile(SSLSocket sslSocket, String filename) throws


Exception {
OutputStream outputStream = sslSocket.getOutputStream();
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE);

FileInputStream fileInputStream = new FileInputStream(filename);


byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
byte[] encryptedBytes = cipher.update(buffer, 0, bytesRead);
outputStream.write(encryptedBytes);
}

byte[] encryptedBytes = cipher.doFinal();


outputStream.write(encryptedBytes);

fileInputStream.close();
}

private static void receiveFile(SSLSocket sslSocket, String filename) throws


Exception {
InputStream inputStream = sslSocket.getInputStream();
Cipher cipher = createCipher(Cipher.DECRYPT_MODE);

FileOutputStream fileOutputStream = new FileOutputStream(filename);


byte[] buffer = new byte[1024];
int bytesRead;

while ((bytesRead = inputStream.read(buffer)) != -1) {


byte[] decryptedBytes = cipher.update(buffer, 0, bytesRead);
fileOutputStream.write(decryptedBytes);
}

byte[] decryptedBytes = cipher.doFinal();


fileOutputStream.write(decryptedBytes);

fileOutputStream.close();
}

private static Cipher createCipher(int mode) throws Exception {


KeyGenerator keyGenerator =
KeyGenerator.getInstance(KEY_ALGORITHM);
keyGenerator.init(KEY_SIZE);
SecretKey secretKey = keyGenerator.generateKey();

Cipher cipher = Cipher.getInstance(ALGORITHM);


byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

cipher.init(mode, secretKey, ivParameterSpec);

return cipher;
}

}
Output
Keystore & truststore
To create the keystore and truststore files without writing any code, you can use
the keytool command-line tool that comes with the Java Development Kit (JDK).
Here are the steps to create the keystore and truststore files using 
keytool
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -keystore
mykeystoreR.jks
keytool -exportcert -alias server -file server.crt -keystore mykeystoreR.jks keytool -
import -alias myserver -keystore mytruststoreR.jks -file server.crt
Keystore and truststore are files used for SSL/TLS communication in Java. They
.contain keys and certificates needed for authentication and encryption
Keystore:
 Contains keys and certificates belonging to the entity (client or server)
owning the keystore.
 Used to authenticate the entity to other parties.
 Contains private keys and public key certificates.
 Password protected.
Truststore:
 Contains trusted CA and public key certificates.
 Used to validate the other party in an SSL communication.
 Only contains public key certificates, no private keys.
 Also password protected.
Some common types of keystores/truststores in Java are JKS (Java Key Store) and
PKCS12.
In the code you shared, the keystore is used by the client and server to authenticate
themselves using their private keys. The truststore is used to validate the other
party's certificate and establish a trusted connection.
Without these files, the SSL handshake cannot be completed successfully and the
connection will not be established.
Conclusion
In conclusion, this report has presented a plan to create a secure file sharing
system using Java security packages. The system will implement authentication,
encryption, and secure communication protocols to ensure the confidentiality and
integrity of the shared files. The authentication feature will require users to
authenticate themselves before accessing any files, and the encryption feature will
encrypt files before they are stored on the server and decrypt them when requested
by authenticated users. The system will also use secure communication protocols
such as SSL/TLS to encrypt all communication between the client and server. By
implementing these features, the system will provide a secure and reliable file
sharing system that can be used in various applications.

You might also like