Skip to content

Repository files navigation

Disclaimer: Cryptographic algorithms are built completely from scratch purely for self-educational purposes. Not for production use!!!

Since custom-rolled cryptography is unprofessional, I also included a fully library-based version of the cryptography in src/main/java/com.example.encryptMsg/cryptogrpahy/EncryptionCompliant.java. The custom version is in EncryptionCustom.java.

To toggle from the custom-rolled version to the library-based version, go to src/main/java/com.example.encryptMsg/service/UserService.java, then find the class constructor and edit @Qualifier("custom") to @Qualifier("compliant").

Running the project

For the all-inclusive experience:

This is a fullstack application; the project files include both the frontend and backend.

Docker and Ollama must be run simultaneously with the project.

  • Locally-installed applications: Docker, Ollama
  • Docker is included to run both simultaneously with all required file dependencies, but this means that Docker itself must be installed locally on the device that runs this project.
  • Meta's Llama 3 is the LLM used for this project. Ollama should be installed and run so that the project can access Llama 3.

Once all setup is completed, open the project root-directory terminal, then enter docker compose up --build. To run the project in the background, instead enter docker compose up --build -d.

To shut down the project, enter docker compose down.

To access the project frontend, enter the URL http://localhost:80/ in your preferred browser.

To try the frontend/backend separately:

Backend: run src/main/java/com.example.encryptMsg/EncryptMsgApplication.java.

Frontend: access src/main/frontend in the terminal/CMD, then enter npm run dev.

Ports: http://localhost:8080/ for backend; http://localhost:5173/ for frontend.

Basic project information

This project was done for self-study on cryptographic algorithms, bitwise operations, branchless constant-time finite-field arithmetic in GF(2^8) and GF(2^128), SpringBoot, Rest API, system design, database interaction, unit-test writing, and UI/UX integration with ReactJS frontend.

The project also demonstrates an interactive honeypot terminal, which implements both deterministic and LLM-supported responses (using Meta's Llama 3).

Additional implementations include Docker Compose, Nginx, and a GitHub security pipeline.

The application asks you to create an account with a username and password, after which it lets you store encrypted text-entries in a database (which is cleared as soon as the backend program is terminated).

This program takes advantage of Java Project Panama (incl. Vector API and MemorySegment).

Features:

  1. Create account (SHA-256 password hashing)
  2. Delete account (eradication of all account data)
  3. Create message (AES-256-GCM or AES-256-CBC message encryption depending on user-choice)
  4. Delete message (eradiation of all message data)
  5. Show all messages upon login (AES-256-GCM/CBC message decryption)

The user's text-entries are encrypted using Rijndael AES-256 cryptography with Galois Counter Mode (GCM) or Cipher Block Chaining (CBC) based on the user's choice during account creation. The user password is encrypted using a one-way SHA-256 hashing algorithm. Passwords are salted and stretched using PBKDF2 (implements HMAC-SHA256).

My core cryptographic algorithms (PBKDF2, SHA-256, AES-256-GCM) are fully custom-rolled with no use of cipher libraries. While custom-rolled cryptography is unprofessional, highly vulnerable to side-channel attacks, and doesn't take advantage of hardware optimizations, I believed it to be worth the practice. The code for all my custom cryptography is found in src/main/java/com.example.encryptMsg/cryptography/EncryptionCustom.java.

As already mentioned at the top, I therefore added a fully library-based version of the cryptography in cryptography/EncryptionCompliant.java.

Additional protection implemented against:

  1. Timing attacks
    1. Solution: constant-time array comparison found in cryptography/customrolled/AES256Universal.java
  2. Man-in-the-middle attacks
    1. Solution: cipher modes (AES-GCM and AES-CBC)
    2. Tested in src/test/java/com.example.encryptMsg/crackingTests
  3. SQL injections
    1. Solution: SpringDataJPA's prepared SQL statements
    2. Tested in crackingTests/Injection_SQL_Tests.java
  4. Padding oracle attacks
    1. Solution: providing the GCM option which doesn't use padding
  5. Rainbow table attacks
    1. Solution: using salt
  6. Brute-force attacks
    1. Solution: PBKDF2 key-stretching with HMAC-SHA256
  7. Time-of-check to Time-of-use race-condition
    1. Solution: immediately using system-state upon access and implementing a global exception handler for the case that the state does not exist
    2. See global exception handler in java/com.example.encryptMsg/GlobalExceptionHandler.java
  8. String literals are not cleared readily by Java's garbage collector
    1. Solution: accepting sensitive data from the frontend, incl. password and message-plaintext, as character-arrays instead of Strings
  9. Sensitive data generally remains in main-memory for quite some time until cleared by Java's garbage collector.
    1. Solution: filling arrays with 0s as soon as they are no longer needed
  10. SpringBoot's JSON parser "Jackson" parses text-inputs as Strings by default
    1. Solution: implemented a class java/com.example.encryptMsg/config/CharArrDeserialization.java which overrides Jackson's deserialization process to parse texts as char-arrays

Strategy patterns (loosely-coupled):

  1. There is a frontend button-row in account-creation with which the user decides whether to use AES-GCM or AES-CBC as the message cipher mode. The choice of cipher-mode is then transmitted to the backend to switch between AES256GCM and AES256CBC classes, respectively.
  2. The editor decides whether the custom-rolled cryptography or the fully library-based cryptography is used by toggling the @Qualifier annotation argument between "custom" and "compliant". The argument determines which of the two CryptographyToggle interface implementations EncryptionCustom and EncryptionCompliant should be used in UserService.

All Rest API communication to the frontend is found in src/main/java/controller/UserController.java.

All unit-tests are found in src/test/java/com.example.encryptMsg/. Mockito is the mocking framework used in UserControllerTest.java and UserServiceTest.java.

It must be noted that all these server-side cybersecurity measures don't really matter if the website isn't run on HTTPS. Having said that, this isn't really an issue on localhost.

Backend development tools

Java 24, SpringBoot 4.1.0, Maven 4.0.0, Jar packaging, Properties configuration

Key dependencies: Spring Web, Spring Boot DevTools, Spring Data JPA, Spring Web MVC, H2 Database

Key plugins: Maven Compiler Plugin, Maven Surefire Plugin, Eirslett Frontend Maven 1.15.1, Maven Resources node 24.12.0 npm 10.2.4

Frontend development tools

TypeScript 6.0.2, React 19.2.8, Vite 8.2.2

NIST documentation

I did my best to design my SHA-256 and AES-256 algorithms in a manner that is faithful to the official documentation by the National Institute of Standards and Technology (NIST).

FIPS 197 (AES): https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf

FIPS PUB 180-4 (SHA): https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

SP 800-38A (CBC): https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf

SP 800-38D (GCM): https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf

FIPS PUB 198-1 (HMAC): https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf

SP 800-132 (PBKDF and salting): https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf

CMVP Overview Page (advice against custom-rolled cryptography): https://csrc.nist.gov/projects/cryptographic-module-validation-program

About

Fullstack LLM-supported application that stores encrypted messages online. SpringBoot + ReactJS Vite + H2 database; fully custom-rolled encryption algorithms (PBKDF2, SHA-256, AES-256-GCM) without cryptography libraries.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages