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

Mar 14, 2025 - 21:01
 0
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:

winget install --id=GnuPG.GnuPG -e

Via: https://winstall.app/apps/GnuPG.GnuPG or https://winget.run/pkg/GnuPG/GnuPG.

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<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!