Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit ffc70e1

Browse files
authored
Merge pull request #52 from noobdevsam/24-add_download_feature
merge from branch 24 - 2
2 parents a6b5222 + 17f86ac commit ffc70e1

File tree

1 file changed

+136
-62
lines changed

1 file changed

+136
-62
lines changed

README.md

Lines changed: 136 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.x-brightgreen.svg)
55
![License](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)
66

7-
This project is a powerful and secure steganography tool built with Spring Boot 3. It allows you to hide text messages or files within images using the Least Significant Bit (LSB) technique. The application provides a RESTful API for all its operations, supports robust AES-256 encryption for hidden data, and includes features like large file streaming to ensure memory efficiency.
7+
This project is a powerful and secure steganography tool built with Spring Boot 3. It allows you to hide text messages or files within images using the Least Significant Bit (LSB) technique. The application provides a RESTful API for all its operations, supports robust AES-256 encryption for hidden data, and is optimized for production with GraalVM native image support and Java Virtual Threads.
88

99
## Table of Contents
1010

@@ -19,82 +19,94 @@ This project is a powerful and secure steganography tool built with Spring Boot
1919
- [Getting Started](#getting-started)
2020
- [Prerequisites](#prerequisites)
2121
- [Cloning the Repository](#cloning-the-repository)
22-
- [Configuration](#configuration)
23-
- [Running the Application (JVM)](#running-the-application-jvm)
22+
- [Configuration](#configuration)
23+
- [Running the Application](#running-the-application)
24+
- [1. For Local Development (JVM)](#1-for-local-development-jvm)
25+
- [2. For Production (Native Docker Image)](#2-for-production-native-docker-image)
2426
- [Interacting with the API](#interacting-with-the-api)
25-
- [Containerization with Docker (Native Image)](#containerization-with-docker-native-image)
27+
- [Example 1: Estimate Capacity](#example-1-estimate-capacity)
28+
- [Example 2: Encode a Text Message](#example-2-encode-a-text-message)
29+
- [Example 3: Decode a Stego Image](#example-3-decode-a-stego-image)
2630
- [Project Structure](#project-structure)
2731
- [Contributing](#contributing)
2832
- [License](#license)
2933

3034
## What is Steganography?
3135

32-
Steganography is the practice of concealing a message, image, or file within another message, image, or file. Unlike cryptography, which obscures the content of a message, steganography conceals the very existence of the message. This tool uses the **Least Significant Bit (LSB)** method, which subtly alters the color data of image pixels to embed information, making the changes virtually invisible to the human eye.
36+
Steganography is the practice of concealing a message or file within another file. Unlike cryptography, which obscures the *content* of a message, steganography conceals the very *existence* of the message. This tool uses the **Least Significant Bit (LSB)** method, which subtly alters the color data of image pixels to embed information, making the changes virtually invisible to the human eye.
3337

3438
## Features
3539

3640
- **Text & File Steganography**: Embed both plain text and binary files within images.
37-
- **Strong Encryption**: All hidden data is encrypted with **AES-256 (CBC mode)** using a key derived from your password via **PBKDF2**.
38-
- **RESTful API**: Easy-to-use endpoints for encoding, decoding, capacity estimation, and managing encodings.
39-
- **GraalVM Native Image Support**: Build a lightweight, fast-starting native executable container using Spring Boot's Maven plugin and Cloud Native Buildpacks.
40-
- **Capacity Estimation**: Before performing an expensive encoding operation, you can estimate if your data will fit in a given image.
41-
- **Large File Streaming**: Efficiently encodes large files by streaming them, keeping memory usage low.
42-
- **Database Integration**: Metadata for each encoding is saved to a MySQL database using Spring Data JPA.
43-
- **Virtual Threads**: Uses Java 25 Virtual Threads with an embedded Jetty server for high-concurrency request handling.
44-
- **Scheduled Cleanup**: A background task cleans up orphaned stego files and expired extracted files.
45-
- **Docker Compose Support**: Includes a `compose.yml` for easy multi-container setup.
41+
- **Strong Encryption**: All hidden data is encrypted with **AES-256 (CBC mode)**. The encryption key is derived from your password using **PBKDF2 with 65,536 iterations** and a unique salt for each encoding.
42+
- **RESTful API**: A comprehensive API for encoding, decoding, capacity estimation, and managing encodings.
43+
- **GraalVM Native Image Support**: Build a lightweight, fast-starting native executable container using the integrated Spring Boot Maven plugin and Cloud Native Buildpacks.
44+
- **High-Concurrency Ready**: Utilizes **Java 25 Virtual Threads** with an embedded Jetty server to efficiently handle a large number of concurrent requests.
45+
- **Large File Streaming**: Efficiently encodes and encrypts large files by streaming them, keeping memory usage low.
46+
- **Capacity Estimation**: A dedicated endpoint to check if your data will fit in a given image before performing the encoding.
47+
- **Database Integration**: Encoding metadata is saved to a MySQL database using Spring Data JPA.
48+
- **Scheduled Cleanup**: A background task periodically cleans up orphaned stego files from storage and deletes expired extracted files.
49+
- **Robust Error Handling**: A global exception handler provides detailed, structured error responses (`ProblemDetail`) for API clients.
50+
- **Traceability**: A `CorrelationIdFilter` adds a unique trace ID to every request for improved logging and debugging.
4651

4752
## How It Works
4853

49-
The application embeds data by modifying the least significant bits of an image's pixel color channels (Red, Green, Blue).
50-
5154
### Encoding Process
5255

5356
1. **Input**: A user provides a cover image, the data to hide (text or a file), and a password.
54-
2. **Encryption**: The data is encrypted using AES-256.
55-
3. **Metadata Creation**: A JSON metadata block is created containing details like LSB depth, data type, and a password verification hash.
56-
4. **LSB Embedding**: The metadata and encrypted data are written into the cover image's pixels.
57+
2. **Encryption**: The data is encrypted using AES-256. A unique salt is generated for each operation.
58+
3. **Metadata Creation**: A JSON metadata block is created containing details like LSB depth, data type, and a **SHA-256 hash** of the encryption key for password verification on decode.
59+
4. **LSB Embedding**: The metadata and encrypted data are written into the least significant bits of the cover image's pixels.
5760
5. **Output**: The modified image is saved as a new, lossless **PNG file**, and its metadata is persisted in the database.
5861

5962
### Decoding Process
6063

61-
1. **Input**: A user provides the stego-image and the password.
62-
2. **Metadata Extraction**: The application reads the image's LSBs to find and extract the metadata.
63-
3. **Password Verification**: It hashes the provided password and compares it to the hash stored in the metadata.
64-
4. **Payload Extraction & Decryption**: The application reads and decrypts the hidden data.
64+
1. **Input**: A user provides the stego-image and the password used for encoding.
65+
2. **Metadata Extraction**: The application reads the image's LSBs to find the "magic number" (`STEG`) and extracts the metadata.
66+
3. **Password Verification**: It derives a key from the provided password, hashes it, and compares it to the hash stored in the metadata. The process fails if they don't match.
67+
4. **Payload Extraction & Decryption**: The application reads the hidden data from the pixels and decrypts it using the password.
6568
5. **Output**: The original text or file is returned.
6669

70+
### Security Model
71+
72+
- **Password Derivation**: The AES key is derived from the user's password and a unique, random **16-byte salt** using **PBKDF2**. This ensures that even identical passwords produce different keys for different encodings.
73+
- **Password Verification**: During decoding, the provided password is used to derive a key, which is then hashed (SHA-256) and compared against the hash stored in the image's metadata. This prevents incorrect password attempts without decrypting the entire payload.
74+
- **Authenticated Encryption**: The use of **CBC mode with PKCS5Padding** and a unique **16-byte Initialization Vector (IV)** ensures that encrypted data is resistant to common cryptographic attacks.
75+
6776
## Technology Stack
6877

6978
- **Java 25** & **Spring Boot 3**
70-
- **GraalVM**: For building a native executable.
71-
- **Spring Web, Data JPA, Jetty**
72-
- **MySQL**: Database for persisting encoding metadata.
73-
- **Maven**: For project and dependency management.
74-
- **Docker & Docker Compose**: For container orchestration.
79+
- **GraalVM**: For building the native executable.
80+
- **Spring Framework**: Web, Data JPA, Jetty (for Virtual Threads).
81+
- **Database**: MySQL.
82+
- **Build & Packaging**: Maven, Spring Boot Buildpacks.
83+
- **Containerization**: Docker & Docker Compose.
84+
- **Utilities**: Lombok, MapStruct.
7585

7686
## API Endpoints
7787

7888
The base path for all endpoints is `/api/v1/stego`.
7989

80-
| Method | Endpoint | Description |
81-
| :------- | :---------------- | :------------------------------------------------------------------------------------------ |
82-
| `GET` | `/estimate` | Estimates the data capacity of an image. |
83-
| `POST` | `/encode/text` | Encodes a text message into a cover image. |
84-
| `POST` | `/encode/file` | Encodes a file into a cover image. |
85-
| `POST` | `/decode` | Decodes a message or file from a stego-image. |
86-
| `POST` | `/metadata` | Extracts steganography metadata from an image. |
87-
| `GET` | `/encodings` | Lists all steganography encodings. |
88-
| `GET` | `/encodings/{id}` | Retrieves a specific encoding by its UUID. |
89-
| `DELETE` | `/encodings/{id}` | Deletes an encoding record and the corresponding stego file. |
90+
| Method | Endpoint | Description |
91+
| :------- | :---------------------------- | :------------------------------------------------------------------------ |
92+
| `GET` | `/estimate` | Estimates the data capacity of an image. |
93+
| `POST` | `/encode/text` | Encodes a text message into a cover image. |
94+
| `POST` | `/encode/file` | Encodes a file into a cover image. |
95+
| `POST` | `/decode` | Decodes a message or file from a stego-image. |
96+
| `POST` | `/metadata` | Extracts steganography metadata from an image without full decoding. |
97+
| `GET` | `/encodings` | Lists all steganography encodings stored in the database. |
98+
| `GET` | `/encodings/{id}` | Retrieves a specific encoding by its UUID. |
99+
| `DELETE` | `/encodings/{id}` | Deletes an encoding record and its associated file. |
100+
| `GET` | `/encodings/{id}/download` | Downloads the specified stego-image file. |
101+
| `GET` | `/download/extracted/{name}` | Downloads a temporarily stored file after decoding. |
90102

91103
## Getting Started
92104

93105
### Prerequisites
94106

95-
- **JDK 25 or higher** (The project is configured for Java 25).
96-
- **Maven 3.8+**.
97-
- **Docker and Docker Compose**.
107+
- **JDK 25 or higher**
108+
- **Maven 3.8+**
109+
- **Docker and Docker Compose**
98110
- A REST client like [Postman](https://www.postman.com/) or `curl`.
99111

100112
### Cloning the Repository
@@ -104,60 +116,122 @@ git clone https://github.com/noobdevsam/spring-project-steganography-tool.git
104116
cd spring-project-steganography-tool
105117
```
106118

107-
### Running the Application (JVM)
119+
## Configuration
120+
121+
The main configuration is in `src/main/resources/application.yml`. Key properties can be overridden with environment variables, which is the standard practice for containerized deployment.
122+
123+
| Property | Environment Variable | Description | Default Value |
124+
| :--------------------------- | :-------------------- | :--------------------------------------------------------------- | :-------------- |
125+
| `spring.datasource.url` | `DATABASE_URL` | JDBC URL for the MySQL database. | `jdbc:mysql://...` |
126+
| `spring.datasource.username` | `DATABASE_USER` | Database username. | `user` |
127+
| `spring.datasource.password` | `DATABASE_PASSWORD` | Database password. | `password` |
128+
| `app.storage.base-path` | `STORAGE_BASE_PATH` | Local directory where files will be stored. | `storage` |
129+
- `app.stream.threshold-bytes`: File size (in bytes) above which streaming is used for encoding. Default: `1MB`.
130+
- `app.cleanup.*`: Settings for the scheduled file cleanup task.
131+
- `app.extraction.temp-ttl-ms`: Time-to-live for extracted files. Default: `5 minutes`.
132+
133+
## Running the Application
134+
135+
There are two primary ways to run the application.
108136

109-
For local development, you can run the application directly on your machine's JVM.
137+
### 1. For Local Development (JVM)
138+
139+
This method is ideal for development and debugging, as it uses Spring Boot's hot-reload capabilities.
110140

111141
1. **Start the Database**:
142+
Open a terminal and run the following command to start the MySQL database service in the background.
112143
```bash
113144
docker compose up -d db-mysql
114145
```
115146

116147
2. **Run the Spring Boot Application**:
148+
In a separate terminal, run the application using the Maven wrapper.
117149
```bash
118150
./mvnw spring-boot:run
119151
```
120-
The application will start on port `8080`.
121-
122-
## Containerization with Docker (Native Image)
152+
The application will start on `http://localhost:8080`.
123153

124-
The recommended way to run the application in production is to build a native image container using the Spring Boot Maven plugin.
154+
### 2. For Production (Native Docker Image)
125155

126-
This process involves two simple steps:
127-
128-
1. **Build the Native Docker Image:**
129-
Run the following Maven command. This will use Cloud Native Buildpacks to compile the application into a native executable and package it into a minimal Docker image named `noobdevsam/spring-project-steganography-tool:0.0.1-SNAPSHOT`.
156+
This is the recommended approach for production. It compiles the application into a native executable and packages it into a minimal, secure Docker container.
130157

158+
1. **Build the Native Docker Image**:
159+
Run the following Maven command. This uses Cloud Native Buildpacks to compile a native executable and create a Docker image named `noobdevsam/spring-project-steganography-tool:0.0.1-SNAPSHOT`.
131160
```bash
132-
# This command can take several minutes to complete
161+
# This command can take several minutes and requires Docker to be running.
133162
./mvnw spring-boot:build-image -Pnative -DskipTests
134163
```
135164

136-
2. **Run with Docker Compose:**
137-
Once the image is built, you can start the application and the database using Docker Compose.
138-
165+
2. **Run with Docker Compose**:
166+
Once the image is built, start the application and the database using Docker Compose.
139167
```bash
168+
# This will use the image built in the previous step.
140169
docker compose up
141170
```
142-
The application will be available on port `8080`. The `storage` directory is mounted as a volume, so your files will persist between container restarts.
171+
The application will be available on `http://localhost:8080`.
172+
173+
To stop all services, press `Ctrl+C` or run `docker compose down`.
174+
175+
## Interacting with the API
176+
177+
### Example 1: Estimate Capacity
178+
179+
Check if a 50KB message fits in a 1024x768 image.
180+
181+
**Request:**
182+
```bash
183+
curl "http://localhost:8080/api/v1/stego/estimate?width=1024&height=768&lsbDepth=1&plainLength=51200"
184+
```
185+
186+
**Response:**
187+
```json
188+
{
189+
"capacityBytes": 294912,
190+
"overheadBytes": 137,
191+
"encryptedBytesEstimate": 51216,
192+
"requiredBytesEstimate": 51353,
193+
"fits": true,
194+
"streamThresholdBytes": 1000000
195+
}
196+
```
197+
198+
### Example 2: Encode a Text Message
199+
200+
Encode the message "secret data" into `cover.png` with password "securepass".
201+
202+
**Request:**
203+
```bash
204+
curl -X POST http://localhost:8080/api/v1/stego/encode/text \
205+
-F "coverImage=@/path/to/your/cover.png" \
206+
-F "message=secret data" \
207+
-F "password=securepass" \
208+
-F "lsbDepth=1"
209+
```
210+
211+
### Example 3: Decode a Stego Image
212+
213+
Decode `stego-image.png` using the password "securepass".
143214

144-
To stop the services, press `Ctrl+C` or run:
215+
**Request:**
145216
```bash
146-
docker compose down
217+
curl -X POST http://localhost:8080/api/v1/stego/decode \
218+
-F "stegoImage=@/path/to/your/stego-image.png" \
219+
-F "password=securepass" \
220+
--output response.json
147221
```
148222

149223
## Project Structure
150224

151-
- `configs/`: Spring configuration classes.
225+
- `configs/`: Spring configuration classes (e.g., `VirtualThreadConfig`).
152226
- `controllers/`: REST controllers for the API.
153-
- `entities/`: JPA entity classes.
227+
- `entities/`: JPA entity classes (`StegoData`).
154228
- `exceptions/`: Custom exceptions and the global exception handler.
229+
- `filters/`: Servlet filters for request processing (`CorrelationIdFilter`).
155230
- `mappers/`: MapStruct DTO-entity converters.
156231
- `models/`: API Data Transfer Objects (DTOs).
157232
- `repos/`: Spring Data JPA repositories.
158233
- `services/`: Business logic interfaces and implementations.
159-
- `cleanup/`: Scheduled cleanup task.
160-
- `filters/`: Servlet filters for request processing.
234+
- `cleanup/`: Scheduled cleanup task for orphaned files.
161235

162236
## Contributing
163237

0 commit comments

Comments
 (0)