ProjectReport
ProjectReport
According to the latest estimates, 328.77 million terabytes of data are created
each day. Protecting and securing the transmission of this data is the key tothe
creation of a better digital world. Data is the pollution problem of the information
age, and protecting privacy is the environmental challenge. In the present
decade, images have become a valuable source of information. They play an
essential role in every field whether it be medical, agriculture, defense or
education. Over the past few years, steganography has received a lot of attention
for passing military sensitive details. The information is passed generally via
image steganography. With the increase in amount to data to hide, other
multimedia formats are gaining popularity too. Secured communication on
sensitive information between two parties need to consider information security
as necessity. Steganography and cryptography can be used to enhance the
information security. Cryptography discloses the availability of information,
whereas steganography hides the availability of information so that no other than
the two communicating parties can recognize it. With advancement in internet
applications the information mainly consists of text, audio, image, and video type
of information. This project provides a detailed analysis and methodology for
Multimedia based steganography of information. Also, we tend to discuss the
available methods and techniques for multimedia steganography and their
performances.
CONTENT
Chapter
TITLE Page No.
No
ABSTRACT vi
1 INTRODUCTION 9-10
REFERENCES 39-40
APPENDIX
A SOURCE CODE 40-65
C CERTIFICATE 77
LIST OF FIGURES
4.4.2 Human.jpeg 36
4.4.3 Animal.jpeg 36
4.4.4 Pic2in1.jpeg 36
viii
CHAPTER 1
INTRODUCTION
Video Steganography: Video steganography hides data within video files. It can be
more challenging than other forms, as it involves both spatial and temporal data.
Techniques often rely on modifying frames or altering specific video characteristics.
9
more protocols simultaneously or the relationships between them – relying on the
modification of their intrinsic properties for the embedding of steganograms.
10
CHAPTER 2
LITERATURE SURVEY
This problem statement has been extensively studied over the past 5 years by
researchers and automotive companies in a bid to create a solution, and all their
solutions vary from analyzing various patterns of distractive habits to analyzing health
vitals of the driver.
The work of Dr. Alluri Harika et al [1] introduced a steganography image imaging
application which is based on the Advanced Encryption Standard (AES) and random
bit technique. The AES technique is used to encrypt the secret message and the
random bit technique is used to hide the encrypted message in the image.
Studies aim to increase the information hiding capacity while maintaining perceptual
quality. Papers like "Adaptive Steganography with Minimization of the Impact on the
Carrier Image" by Dumitrescu et al. [4] explore ways to achieve this balance.
Steganography isn't limited to images; it extends to audio and video. Research papers
such as "Audio Steganography: A Comprehensive Review" by Alzahrani and Almutairi
[5] cover methods and challenges in audio steganography.
Deep learning techniques have also been applied to improve steganography and
steganalysis. "Towards Unsupervised Deep Steganography" by Xu et al. [6] discusses
11
using convolutional neural networks for steganography.
Hardware acceleration, particularly using GPUs, has been a focus in recent research.
"Parallel Steganography and Steganalysis on Graphics Hardware" by Bianchi and Piva
[9] is an example of work in this area.
Security and Detection Remain Critical: Ensuring the security of hidden information and
developing robust steganalysis methods are ongoing challenges. Researchers are
working on both sides of the spectrum, devising more secure embedding techniques
and more effective detection methods.
Balancing Capacity and Quality: Striking a balance between increasing data hiding
capacity and maintaining the perceptual quality of multimedia files is a significant
concern. Research is focused on methods that hide larger amounts of data while
12
minimizing the visual or auditory impact on the carrier file.
Emergence of Deep Learning: Deep learning techniques have made their way into
multimedia steganography, with convolutional neural networks and other modelsbeing
applied to enhance both steganography and steganalysis.
13
exploration of new application areas. Moreover, it underscores the ethical and legal
considerations that researchers and practitioners need to address as steganography
continues to advance.
Capacity vs. Security Trade-off: Balancing the amount of hidden information (capacity)
with the level of security against detection is a fundamental challenge in
steganography. Increasing capacity often leads to a higher chance of detection.
Payload Integrity and Reliability: Ensuring that the hidden information is reliably
extracted without corruption, even in the presence of minor distortions or lossy
compression, is a critical concern.
14
Quantifying Security and Detectability: Developing metrics to quantitatively measure
the level of security provided by a steganographic algorithm, as well as the detectability
by potential adversaries, remains a significant challenge.
15
CHAPTER 3
REQUIREMENT ANALYSIS
Detection Risk: The primary risk in steganography is the potential detection of hidden
information by adversaries or steganalysis techniques. Detection risks could lead to
the exposure of sensitive data or the compromise of covert communication.
Misuse Risk: There is a risk that steganography techniques can be misused for
malicious purposes, such as concealing malware, distributing illegal content, or
bypassing security controls.
Data Loss Risk: When data is embedded within multimedia files, there's a risk of data
loss or corruption during the embedding and extraction processes. If the embedded
data is critical, its loss could have significant consequences.
Privacy Risk: In cases where steganography is used to protect privacy, there's a risk
that the hidden data may be exposed, leading to privacy breaches.
Likelihood: Evaluate the likelihood of each identified risk occurring. Factors that
contribute to likelihood include the sophistication of potential adversaries, the strength
of the steganographic method, and the prevalence of steganalysis techniques.
16
Impact: Assess the potential impact of each risk. Consider the consequences of
detection, misuse, data loss, or privacy breaches.
Secure Key Management: Implement robust key management practices to protect the
steganographic keys. This includes key generation, distribution, and storagestrategies
to prevent unauthorized access.
Compliance with Ethical and Legal Standards: Ensure that the use of steganography
aligns with ethical and legal standards. Avoid activities that may lead to legal
consequences or ethical violations.
Training and Awareness: Provide training and awareness programs to individuals who
use steganography for legitimate purposes. This can help prevent misuse and enhance
security.
17
In conclusion, risk analysis in steganography is crucial for understanding and
addressing the potential threats and vulnerabilities associated with hidden data. By
systematically identifying, assessing, and mitigating risks, organizations and
individuals can make informed decisions about the use of steganography and ensure
the security and privacy of their data.
Multimedia steganography applications, which involve hiding data within audio, image,
or video files, may have slightly higher hardware requirements compared to general
steganography software, as multimedia files can be larger and require more processing
power. Here are the typical hardware requirements for running multimedia
steganography applications:
Memory (RAM): 8GB or more of RAM is recommended for working with multimedia
files and steganography applications. Larger files or complex steganography methods
may benefit from more RAM.
Storage: Adequate storage space for multimedia files is necessary. SSDs are preferred
for faster read and write operations. Free space should accommodate the original
multimedia files, the steganography software, and any output files.
Operating System: Ensure that the multimedia steganography software you plan to use
is compatible with your operating system (e.g., Windows, macOS, or Linux).
18
Display: A standard computer monitor is sufficient for interacting with multimedia
steganography applications.
Sound Card (for audio steganography): If you're working with audio steganography, a
sound card with good audio input/output capabilities may be beneficial.
Remember that the specific requirements can vary depending on the multimedia
steganography application and the complexity of the techniques you plan to use.
19
CHAPTER 4
Text Steganography: The data is concealed within the text. The key knowledge of this
system is concealed behind the nth character in a phrase of the substance of the
document. There are several techniques in a text document to conceal data. They are as
follows: Format Based Method and Random and Statistical Method.
A new approach of text Steganography using ASCII values, this project aims to maximize
the usage capacity (text capability) in text Steganography. A new technique has been
proposed to encrypt the text or content inside the images by using pixel values and ASCII
values. Merging and dividing procedure is the heart of this method and gives the result.
In this technique they give more importance to pixel values. Unlike other techniques, this
model can embed or encrypt all 255 ASCII characters, this approach accessible only for
lossless text formats. The proposed algorithm clients can hide more measures of
information without altering the size of the cover picture. It implies changes reflected are
almost insignificant. This project’s limitation is to improve the efficiency of the
steganographic algorithm for better performance. We suggest a modern methodology of
format-based content Steganography, by utilizing the approach of two content or
steganography approaches that are line-shifting and character or word-shifting strategies
with a copy protection method. Mask the details or material in binary or digitized type
rather than character format by utilizing the above methods and less than one bit is hidden
in of line of cover text, so this approach has a strong hidden ability and less distortion in
the cover text is provided by this process.
20
Fig 4.1: Image Steganography
21
Steganography the formats used are MP4 and MPE are used. In all of these approaches
the main motive is to conceal a secret message in another cover item. This may not be
able to guess the presence of information inside cover media. It is necessary to apply
the proper decoding method to retrieve the information.
Investigated Chaotic Maps: Chaotic systems are very sensitive to initial conditions also
chaotic systems has positive Lyapunov exponent which leads orbital instability.
Moreover, ergodicity property of chaotic systems is also used as a leveraging factor for
hiding information or generating unpredictable random sequences.
The some of the well-known chaotic mapping methods used in this study are:
22
• Logistics Map formula is given at Eq. (1)
• Tent Map formula is given at Eq. (2)
• Quadratic Map formula is given at Eq. (3)
• Bernoulli Map formula is given at Eq. (4)
• Sine Map formula is given at Eq. (5)
• Chebyshev Maps formula is given at Eq.(6)
As it could be observed from given chaotic map equations are all effected by the previous
states. Therefore, those maps are sensitive to initial conditions also guessing the next
outcome of the map is difficult unless the initial conditions are known.
Evaluation Criteria: The authors of the study have determined the invisibility, load capacity
and robustness criteria against steganalysis and attacks. These their metric is used to
assess the steganographic systems. In their work at statistical indeterminacy is also
accepted as requirement.
23
the quality of the stego image one important metric is PSNR (peak signal noise ratio).
Security- the hidden message should be secure even if stego image is identified. This is
generally obtained incorporating encryption scheme before embedding inside the cover
image. Chaotic systems are employed in this study to achieve and obtain a layer of
security since message will be hidden in different location, retrieving of the original text
will be hard even without encryption.
Payload capacity– it is defined as the amount secret message which that can be
unnoticeable embedded in a digital media. The amount of message should not cause
distortion of in the cover image. Bit Per Pixel rate can be used to measure, In this study
it is aimed to investigate the effects of different type of chaotic maps on the
imperceptibility property.
In order to evaluate aforementioned metrics and also assess quality of the stego image
Entropy, Correlation analysis, MSE (mean squared error) and PSRN (Peak Signal Noise
Ratio) are calculated. Equations form (7) to (10) are the given evaluation metrics:
24
Figure 4.1.3 Flowchart of Encryption Process
Proposed Model and Evaluations: In the conventional LSB steganography, just LSB bit of
the carrier image is changed with the secret message bit. At first Secret message is
preprocessed as a bit vector. Secret message embedding location in the cover image is
selected by Chaotic maps. At this study only blue channel of the carrier image has been
alter. Chaotic maps are used to pick a Algorithm of the proposed methodology is given
below:
Algorithm 1
25
Algorithm for Embedding Message
Inputs: Cover image C, Message M, Keys Arrays: Coefficients and initial starting
point of Chaotic Maps Obtain Gzip of the Message M -> ZM
LIST ZM: Message Possible Locations
LIST : Cover Image Possible Locations TEMP:
Outputs: Stego Image
1- For j:0 to ZM
2- location=Generate Random Locations in the LIST ZM using Chaotic Map
3- Assign LIST ZM[location] message to TEMP
4- For i:0 to 7
5- Generate Random locations in the LIST using Chaotic Map
6- Remove the selected location from the LIST
7- Take mod 3 of Chaotic Location to Find the embedding channel
//0 Red, 1 Green, 2 Blue Channel
8- EMBED The LSB of the selected channel of the selected pixel with the
TEMP[i] bit
9- End For
10- Remove the selected ZM[location] from the LISTZM
11- End For
12- Return Stego Image
The software for implementing and testing the proposed model/system for
encryption/decryption using above methodology plays a pivotal role in the project's
success.
Testing software using Java typically involves using various testing frameworks and
libraries to ensure the quality and reliability of Java applications. Here are some common
approaches and tools for testing software in Java:
JUnit: JUnit is one of the most popular Java testing frameworks for writing and running
unit tests. It allows you to define test cases, assert expected outcomes, and automate
27
the testing process.
TestNG: TestNG is another widely used testing framework that provides more advanced
features compared to JUnit. It supports various testing strategies, including unit testing,
integration testing, and end-to-end testing.
Mockito: Mockito is a Java mocking framework that helps you create mock objects for
testing. It's useful for isolating the code under test and simulating interactions with
dependencies.
Test frameworks in Java IDEs: Integrated Development Environments (IDEs) like Eclipse
and IntelliJ IDEA have built-in support for running and debugging Java tests. You can
create and execute test cases directly within your IDE.
Continuous Integration (CI) Tools: CI tools like Jenkins, Travis CI, and CircleCI can
be integrated with your Java projects to automate the testing process, run tests on each
code commit, and generate reports.
Load Testing: For performance testing, tools like Apache JMeter can be used in
combination with Java to simulate and analyze the behavior of an application under load.
Test Automation Frameworks: When building complex test suites or end-to-end tests, you
can create custom test automation frameworks in Java to manage and organize your
tests efficiently.
28
Table 1 Study of Various types of Chaotic Mapping Methods
29
CHAPTER 5
IMPLEMENTATION DETAILS
Spring Boot’s executable jars are ready-made for most popular cloud PaaS (Platform- as-
a-Service) providers. These providers tend to require that you “bring your owncontainer”.
They manage application processes (not Java applications specifically), so they need an
intermediary layer that adapts your application to the cloud’s notion of a running process.
Two popular cloud providers, Heroku and Cloud Foundry, employ a “buildpack” approach.
The buildpack wraps your deployed code in whatever is needed to start your
application. It might be a JDK and a call to java, an embedded web server, or a full-fledged
application server. A buildpack is pluggable, but ideally you should be able to get by with
as few customizations to it as possible. This reduces the footprint of functionality that is
not under your control. It minimizes divergence between development and production
environments.
Ideally, the application, like a Spring Boot executable jar, has everything that it needs to
run packaged within it.
Environment variables do not always make for the easiest API, so Spring Boot
automatically extracts them and flattens the data into properties that can be accessed
through Spring’s Environment abstraction, as shown in the below code:
All Cloud Foundry properties are prefixed with vcap. You can use vcap properties to
access application information (such as the public URL of the application) and service
information (such as database credentials).
30
Figure 5.1 Deployment Code
In addition to running Spring Boot applications by using java -jar directly, it is also possible
to run them as systemd, init.d or Windows services. systemd is the successor of the
System V init system and is now being used by many modern Linux distributions. Spring
Boot applications can be launched by using systemd ‘service’ scripts. The user that runs
the application, the PID file, and the console log file are managed by systemd itself and
therefore must be configured by using appropriate fields in the ‘service’ script.
When executed as root, as is the case when root is being used to start an init.d service,
the default executable script runs the application as the user specified in the
RUN_AS_USER environment variable. When the environment variable is not set, the
user who owns the jar file is used instead. You should never run a Spring Boot application
as root, so RUN_AS_USER should never be root and your application’s jar file should
never be owned by root. Instead, create a specific user to run your application and set
the RUN_AS_USER environment variable or use chown to make it the owner of the jar
file.
If root is used to control the application’s service and you use a .conf file to customize its
startup, the .conf file is read and evaluated by the root user. It should be secured
31
accordingly. Use chmod so that the file can only be read by the owner and use chown to
make root the owner. It often makes sense to customize elements of the start script as it
is written into the jar file. For example, init.d scripts can provide a “description”. Since you
know the description up front (and it need not change), you may as well provide it when
the jar is generated.
With the exception of JARFILE and APP_NAME, the settings listed in the preceding
section can be configured by using a .conf file. The file is expected to be next to the jar
file and have the same name but suffixed with .conf rather than .jar. For example, ajar
named /var/myapp/myapp.jar uses the configuration file named
/var/myapp/myapp.conf, as shown:
If you are running your application from a container, you can use an executable jar, but
it is also often an advantage to explode it and run it in a different way. Certain PaaS
implementations may also choose to unpack archives before they run. For example,
Cloud Foundry operates this way. One way to run an unpacked archive is by starting the
appropriate launcher, as follows:
$ java org.springframework.boot.loader.launch.JarLauncher
This is actually slightly faster on startup (depending on the size of the jar) than running
from an unexploded archive. After startup, you should not expect any differences. Once
you have unpacked the jar file, you can also get an extra boost to startup time by running
the app with its "natural" main method instead of the JarLauncher.
32
It’s beneficial for the startup time to run your application using the AOT generated
initialization code. First, you need to ensure that the jar you are building includes AOT
generated code. For Maven, this means that you should build with -Pnative to activate
the native profile:
$ mvn -Pnative package
For Gradle, you need to ensure that your build includes the org.springframework.boot.aot
plugin. When the JAR has been built, run it with spring.aot.enabled system property set
to true.
33
Fig 5.2.2: Image Steganography Implementation
34
CHAPTER 6
RESULTS AND DISCUSSION
The introduction of an image in another image produces noise which makes it obvious for
the steganalysts to decipher the enciphered media. The use of LSB Chaotic Mapping
algorithm makes it harder for the programmers to find the pixels which have been modified
to embed the secret image. Even if they are successful in doing so, it would be harder for
them to join the pictures into something meaningful. This algorithm does not use regular
pixel values which makes it unique.
A comprehensive and comparative study has been done with the original image and the
enciphered image for the changes. The table depicts the usage of various available
chaotic mapping algorithms and their different evaluation parameters. It also
encompasses various error calculation methods and changes in the entropies according
to the formulas and equations mentioned.
These days, data and information are highly valued, and transmitting and receiving data
securely is crucial. The methods utilized for secure transmission and private information
protection are cryptography and steganography. Current methods combine LSB encoding
steganography with cryptographic algorithms for encryption. They also introduce several
methods for LSB encoding using Chaotic Maps. In many eHealth applications, such as
data management, identity theft prevention, storage, and retrieval,
35
image security is crucial. This paper includes a brief explanation of few well-known picture
assaults that are used to test the performance of the suggested algorithms on images. In
order to encourage more study in this field, we have covered the cryptographic technique
and its traits, types, prerequisites, working domain, and probable problems. Moreover,
various performance measures for assessing algorithms have been shown. The paper
presents a methodology for video steganography that uses text, audio, and image files.
A carrier video is retrieved, and the frames that the audio, text, and image files can be
inserted within are used to reconstruct the video. According to the mathematical model,
the suggested architecture should perform better than the current approaches.
Figure
36
Figure 4.4.5 Encryption Webpage
37
CHAPTER 7
CONCLUSION
38
REFERENCES
[1] Artz, D. 2021. Digital steganography: Hiding data within data. IEEE Internet Computing Journal,
5(3):75-80.
[2] J. Fridrich, M. Goljan and Rui Du, Detecting LSB steganography in color, and gray-scaleimages,
IEEE Multimedia, vol. 8, no. 4, pp. 22- 28, Oct.-Dec. 2021, doi: 10.1109/93.959097
[3] C. Kurak, J. McHugh, A cautionary note on image downgrading, in: Proceedings of the IEEE 8th
Annual Computer Security Applications Conference, 30 November–4December, 2022, pp. 153–
159.
[4] W. Bender, W. Butera, D. Gruhl, R. Hwang, F.J. Paiz, S. Pogreb, Applications for data hiding,
IBM Systems Journal 39 (3&4) (2022)547–568.
[5] Y. Chen, H. Wang, H. Wu, Z. Wu, T. Li, and A. Malik, “Adaptive video data hiding through cost
assignment and STCs,” IEEE Trans. Dependable Secure Comput., vol. 18, no. 3, pp. 1320– 1335,
Jun. 2021.
[6] V. Holub and J. Fridrich, “Designing steganographic distortion using directional filters,” inProc.
IEEE 4th Int. Workshop Inf. Forensics Secur., 2020, pp. 234–239.
[7] Ren T, Kotera M, Ogawa T, et al. Text-Guided Style Transfer-based Image Manipulation Using
Multimodal Generative Models. IEEE Access, 2021, PP(99):1-1.
[8] Taburet T, Bas P, Sawaya W, et al. Natural Steganography in JPEG Domain with a Linear
Development Pipeline. IEEE Transactions on Information Forensics and Security, 2020, PP(99):1-
1.
[9] Petitcolas FAP, et al. “Information hiding-a survey”. Proceedings of the IEEE, 87(7), 1062- 1078,
2020.
[10] S. Xu, et al. “No-reference/Blind Image Quality Assessment: A Survey,” IETE Tech. Rev.
(Institution Electron. Telecommun. Eng. India), vol. 34, pp. 223–245, 2017.
[12] C. Kurak, J. McHugh, A cautionary note on image downgrading, in: Proceedings of the IEEE
8th Annual Computer Security Applications Conference, 30 November–4 December, 2022, pp.
153–159.
39
[13] W. Bender, W. Butera, D. Gruhl, R. Hwang, F.J. Paiz, S. Pogreb, Applications for datahiding,
IBM Systems Journal 39 (3&4) (2022)547–568.
[14] Y. Chen, H. Wang, H. Wu, Z. Wu, T. Li, and A. Malik, “Adaptive video data hiding through
cost assignment and STCs,” IEEE Trans. Dependable Secure Comput., vol. 18, no. 3, pp. 1320–
1335, Jun. 2021.
[15] V. Holub and J. Fridrich, “Designing steganographic distortion using directional filters,” in Proc.
IEEE 4th Int. Workshop Inf. Forensics Secur., 2020, pp. 234–239.
[16] Ren T, Kotera M, Ogawa T, et al. Text-Guided Style Transfer-based Image Manipulation Using
Multimodal Generative Models. IEEE Access, 2021, PP(99):1-1.
[17] Taburet T, Bas P, Sawaya W, et al. Natural Steganography in JPEG Domain with a Linear
Development Pipeline. IEEE Transactions on Information Forensics and Security, 2020, PP(99):1-
1.
[18] Petitcolas FAP, et al. “Information hiding-a survey”. Proceedings of the IEEE, 87(7), 1062-
1078, 2020.
[19] S. Xu, et al. “No-reference/Blind Image Quality Assessment: A Survey,” IETE Tech. Rev.
(Institution Electron. Telecommun. Eng. India), vol. 34, pp. 223–245, 2017.
40
APPENDIX
A. SOURCE CODE
// FileDemoApplication.java
package com.example.filedemo;
import com.example.filedemo.property.FileStorageProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties({
FileStorageProperties.class,
})
SpringApplication.run(FileDemoApplication.class, args);
// FileStorageService.java
package com.example.filedemo.service;
import com.example.filedemo.exception.FileStorageException;
import com.example.filedemo.exception.MyFileNotFoundException;
import com.example.filedemo.property.FileStorageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
41
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@Service
@Autowired
this.coverFileStorageLocation = Paths.get("spring-boot-file-upload-download-
rest-api-example/src/main/resources/cover-file");
this.secretFileStorageLocation = Paths.get("spring-boot-file-upload-
download-rest-api-example/src/main/resources/secret-file");
this.encryptedFileStorageLoacation = Paths.get("spring-boot-file-upload-
download-rest-api-example/src/main/resources/encrypted-file");
try {
Files.createDirectories(this.coverFileStorageLocation);
Files.createDirectories(this.secretFileStorageLocation);
Files.createDirectories(this.encryptedFileStorageLoacation);
42
} catch (Exception ex) {
try {
if(fileName.contains("..")) {
// Copy file to the target location (Replacing existing file with the same
name)
Files.copy(file.getInputStream(), targetLocation,
StandardCopyOption.REPLACE_EXISTING);
return fileName;
43
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
if(fileName.contains("..")) {
// Copy file to the target location (Replacing existing file with the same
name)
Files.copy(file.getInputStream(), targetLocation,
StandardCopyOption.REPLACE_EXISTING);
return fileName;
try {
Path filePath =
this.coverFileStorageLocation.resolve(fileName).normalize();
if(resource.exists()) {
return resource;
} else {
44
}
// ImageSteganography.java
package com.example.filedemo.service;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.filedemo.exception.FileStorageException;
import com.example.filedemo.property.FileStorageProperties;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
@Service
//System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
nu.pattern.OpenCV.loadLocally();
if(coverFolder.listFiles().length != 0) {
if(secretFolder.listFiles().length != 0) {
output = "spring-boot-file-upload-download-rest-api-
example/src/main/resources/encrypted-file/encrypted-file.png";
return this.input1;
return this.input2;
46
public String getEncryptedFileLocation() {
return this.output;
//System.out.println(i + " " + j + " " + k + " " + temp1 + " " + temp2);
String s1 = Integer.toBinaryString(temp1);
String s2 = Integer.toBinaryString(temp2);
s1 = ("00000000" + s1).substring(s1.length());
s2 = ("00000000" + s2).substring(s2.length());
mat1.put(i, j, data1);
}
47
}
Imgcodecs.imwrite(output, mat1);
String s = Integer.toBinaryString(temp);
s = ("00000000" + s).substring(s.length());
//System.out.println(i + " " + j + " " + k + " " + s1 + " " + s2);
mat1.put(i, j, data1);
mat2.put(i, j, data2);
String ch = String.valueOf((char)(random.nextInt(2)+48));
return String.valueOf(ch+ch+ch+ch);
// FileStorageProperties.java
package com.example.filedemo.property;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "cover")
return uploadDir;
this.uploadDir = uploadDir;
}
49
}
// UploadFileResponse.java
package com.example.filedemo.payload;
this.fileName = fileName;
this.fileDownloadUri = fileDownloadUri;
this.fileType = fileType;
this.size = size;
return fileName;
this.fileName = fileName;
return fileDownloadUri;
this.fileDownloadUri = fileDownloadUri;
50
}
return fileType;
this.fileType = fileType;
return size;
this.size = size;
// FileStorageException.java
package com.example.filedemo.exception;
super(message);
super(message, cause);
// MyFileNotFoundException.java
package com.example.filedemo.exception;
51
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
super(message);
super(message, cause);
// FileController.java
package com.example.filedemo.controller;
import com.example.filedemo.payload.UploadFileResponse;
import com.example.filedemo.service.FileStorageService;
import com.example.filedemo.service.ImageSteganography;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
52
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.io.*;
import java.io.FileInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@RestController
@Autowired
@Autowired
@PostMapping("/uploadCoverFile")
53
String fileDownloadUri =
ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
file.getContentType(), file.getSize());
@PostMapping("/uploadSecretFile")
String fileDownloadUri =
ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
file.getContentType(), file.getSize());
@GetMapping("/getEncryptedImage")
54
File file = new File(output);
try {
OutputStream os = fileItem.getOutputStream();
IOUtils.copy(input, os);
// Or faster..
// do something.
String fileDownloadUri =
ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(output)
.toUriString();
@GetMapping("/downloadFile/{fileName:.+}")
55
fileName, HttpServletRequest request) {
try {
contentType =
request.getServletContext().getMimeType(resource.getFile().getAbsolutePath(
));
if(contentType == null) {
contentType = "application/octet-stream";
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;
filename=\"" + resource.getFilename() + "\"")
.body(resource);
// FileDemoApplicationTests.java
package com.example.testingweb;
import org.junit.jupiter.api.Test;
56
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class HttpRequestTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void greetingShouldReturnDefaultMessage() throws Exception {
assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/",
String.class)).contains("Hello, World");
}
// application.properties
## MULTIPART (MultipartProperties)
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=2KB
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=215MB
57
## File Storage Properties
# Please change this to the path where you want the uploaded files to be stored.
file.upload-dir=spring-boot-file-upload-download-rest-api-
example/src/main/resources/cover-file
secret.file.upload-dir=spring-boot-file-upload-download-rest-api-
example/src/main/resources/secret-file
// index.html
<!DOCTYPE html>
<html>
<head>
<title>Steganography</title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css
">
</head>
<body>
<noscript>
</noscript>
<div class="upload-container">
<div class="upload-header">
58
<h2>Upload Files to Hide</h2>
</div>
<div class="upload-content">
<div class="cover-upload">
</form>
<div class="upload-response">
<div id="coverFileUploadError"></div>
<div id="coverFileUploadSuccess"></div>
</div>
</div>
<br>
<br>
<div class="secret-upload">
</form>
<div class="upload-response">
59
<div id="secretFileUploadError"></div>
<div id="secretFileUploadSuccess"></div>
</div>
</div>
<br><br>
<div class="generate-image">
</form>
<div class="upload-response">
<div id="encryptedFileDownloadError"></div>
<div id="encryptedFileDownloadSuccess"></div>
</div>
</div>
</div>
</div>
<div class="footer-basic">
<footer>
<ul class="list-inline">
</ul>
</footer>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-
bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>
// main.js
'use strict';
var coverFileUploadSuccess =
document.querySelector('#coverFileUploadSuccess');
var secretFileUploadSuccess =
document.querySelector('#secretFileUploadSuccess');
function uploadCoverFile(file) {
formData.append("file", file);
xhr.open("POST", "/uploadCoverFile");
xhr.onload = function() {
console.log(xhr.responseText);
if(xhr.status == 200) {
coverFileUploadError.style.display = "none";
coverFileUploadSuccess.style.display = "block";
} else {
coverFileUploadSuccess.style.display = "none";
xhr.send(formData);
function uploadSecretFile(file) {
xhr.open("POST", "/uploadSecretFile");
xhr.onload = function() {
console.log(xhr.responseText);
if(xhr.status == 200) {
secretFileUploadError.style.display = "none";
secretFileUploadSuccess.style.display = "block";
} else {
secretFileUploadSuccess.style.display = "none";
xhr.send(formData);//contentType(MediaType.parseMediaType(contentType))
coverUploadForm.addEventListener('submit', function(event){
if(files.length === 0) {
coverFileUploadError.style.display = "block";
}
63
uploadCoverFile(files[0]);
event.preventDefault();
}, true);
secretUploadForm.addEventListener('submit', function(event){
if(files.length === 0) {
secretFileUploadError.style.display = "block";
uploadSecretFile(files[0]);
event.preventDefault();
}, true);
function generateImage() {
xhr.open("GET", "/getEncryptedImage");
xhr.onload = function() {
console.log(xhr.responseText);
if(xhr.status == 200) {
encryptedError.style.display = "none";
encryptedSuccess.style.display = "block";
} else {
encryptedSuccess.style.display = "none";
64
encryptedError.innerHTML = (response && response.message) || "Some
Error Occurred";
xhr.send();
65