How to Automate Encryption with C++ Script
The other day I noticed that I had compressed several files as backups on a DVD media (the DVDs were at least 15 years old) and I had also encrypted all of them with GnuPG. And all of these files had the same password for .gpg and I needed to know what was inside them. Since many of the files were very long, there were even files larger than 5GB =) I was about to start writing the shell script code to decrypt and unpack them all at once to find out what was inside them. But, I remembered the limpeza command and this could be quick to write the code, but it would take me a lot of time to execute. I could use the GPGME API and create it directly via C++ code, but it's not a complete application, it's just a basic little script!!! So, I decided, once again, to create a script that could be done with GNU Bash in C++. Introduction First, what is GnuPG? GnuPG is the acronym for: "GNU Privacy Guard (GnuPG or GPG)" is a free software alternative to Symantec's PGP cryptographic software suite. GnuPG is part of the Free Software Foundation and the GNU Project. In addition, it received great sponsorship from the German Government. Installing GnuPG Use your operating system's package manager, examples: On Windows winget install --id=GnuPG.GnuPG -e Via: https://winstall.app/apps/GnuPG.GnuPG or https://winget.run/pkg/GnuPG/GnuPG. On macOS brew install gnupg Via: https://formulae.brew.sh/formula/gnupg On Ubuntu sudo apt install gnupg Basic use of GnuPG Let's suppose you have a folder named files/ and you compressed it in .zip format and it became: files.zip. If you want to protect it with a password and encryption, just run the command: gpg -c files.zip Next, you will be asked for a password and confirmation of the password to create the file: files.zip.gpg. Only those who have access to this password will be able to decrypt it. The cool (and dangerous) thing is that you can enter the password via the command line, both for encryption and decryption, and this can save you time from having to enter interactive mode and type password after password... And it was thinking about not suffering from this repetitive boredom/stress that I had this idea! Creating the C++ script First of all, these .gpg type files were mixed with other types of files and I didn't want to filter them, because keeping them where they were was ideal before sending them to my local server here at home. So, they will also include the header to handle these files: #include #include #include namespace fs = std::filesystem; int main(){ // Indicate the path of the folder, in this case, where the script is std::string directory_path = "./"; std::vector gpg_files {}; // Check if directory exists if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) { std::cerr

The other day I noticed that I had compressed several files as backups on a DVD media (the DVDs were at least 15 years old) and I had also encrypted all of them with GnuPG.
And all of these files had the same password for .gpg
and I needed to know what was inside them.
Since many of the files were very long, there were even files larger than 5GB =)
I was about to start writing the shell script code to decrypt and unpack them all at once to find out what was inside them.
But, I remembered the limpeza command and this could be quick to write the code, but it would take me a lot of time to execute.
I could use the GPGME API and create it directly via C++ code, but it's not a complete application, it's just a basic little script!!!
So, I decided, once again, to create a script that could be done with GNU Bash in C++.
Introduction
First, what is GnuPG?
GnuPG is the acronym for: "GNU Privacy Guard (GnuPG or GPG)" is a free software alternative to Symantec's PGP cryptographic software suite.
GnuPG is part of the Free Software Foundation and the GNU Project. In addition, it received great sponsorship from the German Government.
Installing GnuPG
Use your operating system's package manager, examples:
- On Windows
winget install --id=GnuPG.GnuPG -e
Via: https://winstall.app/apps/GnuPG.GnuPG or https://winget.run/pkg/GnuPG/GnuPG.
- On macOS
brew install gnupg
- On Ubuntu
sudo apt install gnupg
Basic use of GnuPG
Let's suppose you have a folder named files/
and you compressed it in .zip
format and it became: files.zip
.
If you want to protect it with a password and encryption, just run the command:
gpg -c files.zip
Next, you will be asked for a password and confirmation of the password to create the file: files.zip.gpg
. Only those who have access to this password will be able to decrypt it.
The cool (and dangerous) thing is that you can enter the password via the command line, both for encryption and decryption, and this can save you time from having to enter interactive mode and type password after password...
And it was thinking about not suffering from this repetitive boredom/stress that I had this idea!
Creating the C++ script
First of all, these .gpg
type files were mixed with other types of files and I didn't want to filter them, because keeping them where they were was ideal before sending them to my local server here at home. So, they will also include the
header to handle these files:
#include
#include
#include
namespace fs = std::filesystem;
int main(){
// Indicate the path of the folder, in this case, where the script is
std::string directory_path = "./"; std::vector<std::string> gpg_files {};
// Check if directory exists
if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
std::cerr << "Directory does not exist or is not valid." << std::endl;
return 1;
}
// Iterate over files in directory
for (const auto& entry : fs::directory_iterator(directory_path)) {
if (entry.is_regular_file() && entry.path().extension() == ".gpg") {
gpg_files.push_back(entry.path().filename().string()); }
}
// Optional
// Displays the names of the .gpg files found
std::cout << "Found .gpg files:" << std::endl;
for (const auto& file : gpg_files) {
std::cout << file << ' ';
}
std::cout.put('\n');
// Set the password for all files
std::string str = "SECRET_PASSWORD";
}
Now just run the command to decrypt the files found and listed:
for (const auto& file : gpg_files) {
std::string com = "gpg --yes --batch --passphrase=" + str + " " + file + " 2>/dev/null"; std::cout << "Decrypting: " << file << std::endl;
std::system(com.data());
}
I would still automatically unpack them by adding them to the loop
, but I gave up, in this case using the extract command because the types could vary: zip
, rar
, tar.gz
,...
// filename equals file to separate the logic
std::string filename = file;
// Remove the .gpg from the filename
if (filename.size() >= 4) {
filename = filename.substr(0, filename.size() - 4);
}
// Execute
std::string extract = "/usr/bin/extract " + filename;
std::cout << extract << std::endl;
std::system(extract.data());
I gave up doing this because it would mix up my specific task, and then I tried it, but the result was not so good.
The complete code is: decript.cpp
#include
#include
#include
namespace fs = std::filesystem;
int main(){
// Indicate the path of the folder, in this case, where the script is
std::string directory_path = "./";
std::vector<std::string> gpg_files {};
// Check if the directory exists
if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
std::cerr << "The directory does not exist or is not valid." << std::endl;
return 1; }
// Iterate over the files in the directory
for (const auto& entry : fs::directory_iterator(directory_path)) {
if (entry.is_regular_file() && entry.path().extension() == ".gpg") {
gpg_files.push_back(entry.path().filename().string());
}
}
// Optional
// Print the names of the .gpg files found
std::cout << "Found .gpg files:" << std::endl;
for (const auto& file : gpg_files) {
std::cout << file << ' ';
}
std::cout.put('\n');
// Set the password for all files
std::string str = "SECRET_PASSWORD"; }
If you want to do the same script, but to create .gpg
files with passwords dynamically, replace com
with:
std::string com = "gpg --yes --batch --passphrase=" + str + " -c " + file;
Note the use of
-c
.
Final script
decript.cpp
#include
#include
#include
namespace fs = std::filesystem;
int main(){
std::string directory_path = "./";
std::vector<std::string> gpg_files {};
if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
std::cerr << "The directory does not exist or is not valid." << std::endl;
return 1;
}
for (const auto& entry : fs::directory_iterator(directory_path)) {
if (entry.is_regular_file() && entry.path().extension() == ".gpg") {
gpg_files.push_back(entry.path().filename().string());
}
}
std::cout << ".gpg files found:" << std::endl;
for (const auto& file : gpg_files) {
std::cout << file << ' ';
}
std::cout << "\n\n";
std::string str = "SECRET_PASSWORD";
for (const auto& file : gpg_files) {
std::string com = "gpg --yes --batch --passphrase=" + str + " " + file + " 2>/dev/null";
std::cout << "Decrypting: " << file << std::endl;
int run = std::system(com.data());
if(run != 0){
std::cerr << "Failed to run: " << com << std::endl;
}
}
return EXIT_SUCCESS;
}
If you want to ensure that there is no memory violation, compile:
g++ -g -Wpedantic -Wall -Werror -fsanitize=address decript.cpp
But, to run, add more speed in execution:
g++ -Ofast decript.cpp
Then just run: ./a.out
.
To extract, I used a script in Terlang:
vim unzip.ter
auto files = {"TheDir.tar.gz", "MyFolder.zip", "BigData.tar.gz"}
auto filesSize = 3
for(auto i = 0; i < filesSize; ++i){
output("Unpacking: " + files[i])
exec("extract " + files[i])
}
And so, I did, in my own way, a task that could take me a long time, quickly and practically!