DEV Community

Cover image for Como Automatizar Criptografia com script C++
Marcos Oliveira
Marcos Oliveira

Posted on

2

Como Automatizar Criptografia com script C++

🚀 Da série C++ como Shell Script


Dia desse eu notei que havia compactado diversos arquivos como backup em uma mídia de DVD(os DVDs tinham pelo menos uns 15 anos) e também havia criptografado todos eles com GnuPG.

E todos esses arquivos tinham a mesma senha para o .gpg e eu precisava saber o que havia dentro deles.

Como muitos eram arquivos de muito tempo, haviam até arquivos de mais 5GB =)

Eu já ia começar a escrever o código shell script para descriptografar e descompactar todos de uma vez só pra descobrir o que havia dentro deles.

Mas, lembrei do comando limpeza e isso poderia ser rápido em escrever o código, mas iria me tomar muito tempo na execução.

Eu poderia usar a API do GPGME e criar ele diretamente via código C++, mas não se trata de uma aplicação completa, é só um scriptzinho básico!!!

Então, decidi, mais uma vez, criar um script que poderia ser feito com GNU Bash em C++.


Introdução

Primeiramente, o que é o GnuPG?

GnuPG é o acrônimo/sigla para: "GNU Privacy Guard (GnuPG ou GPG)" é um software livre alternativo ao conjunto de softwares criptográficos PGP da Symantec.

GnuPG é parte da Free Software Foundation e do Projeto GNU. Além disso, ele recebeu grande patrocínio do Governo Alemão.

Instalação do GnuPG

Use o gerenciador de pacotes do seu sistema operacional, exemplos:

winget install --id=GnuPG.GnuPG  -e
Enter fullscreen mode Exit fullscreen mode

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

brew install gnupg
Enter fullscreen mode Exit fullscreen mode

Via: https://formulae.brew.sh/formula/gnupg

  • No Ubuntu
sudo apt install gnupg
Enter fullscreen mode Exit fullscreen mode

Uso básico do GnuPG

Suponhamos que você possua uma pasta de nome files/ e compactou ela em formato .zip e ele se tornou: files.zip.

Se você quiser proteger com senha e criptografia, basta rodar o comando:

gpg -c files.zip
Enter fullscreen mode Exit fullscreen mode

Em seguida lhe será solitada uma senha e a confirmação da senha para criar o arquivo: files.zip.gpg. Só quem tem acesso a essa senha conseguirá descriptografar.

O legal(e perigoso) é que você pode inserir a senha via linha de comando, tanto para criptografar quanto para descriptografar e isso pode lhe poupar tempo de ficar toda hora entrando no modo interativo e digitar senha por senha...

E foi pensando em não sofrer esse tédio/estresse repetitivo que eu tive essa ideia!


Criando o script C++

Antes de mais nada esses arquivos do tipo .gpg estavam misturados com outros tipos de arquivos e eu não queria filtrar, pois manter onde eles estavam era o ideal antes de mandar eles pro meu server local aqui em casa. Então, vão incluir também o cabeçalho <filesystem> para tratar esses arquivos:

#include <iostream>
#include <filesystem>
#include <vector>

namespace fs = std::filesystem;


int main(){
  // Indicar o caminho da pasta, nesse caso, onde está o script
  std::string directory_path = "./";
  std::vector<std::string> gpg_files {};

  // Verificar se o diretório existe
  if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
    std::cerr << "O diretório não existe ou não válido." << std::endl;
    return 1;
  }

  // Iterar sobre os arquivos no diretório
  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());
    }
  }

  // Opcional
  // Exibe os nomes dos arquivos .gpg encontrados
  std::cout << "Arquivos .gpg encontrados:" << std::endl;
  for (const auto& file : gpg_files) {
    std::cout << file << ' ';
  }
  std::cout.put('\n');

  // Definir a senha para todos os arquivos
  std::string str = "SENHA_SECRETA";
}
Enter fullscreen mode Exit fullscreen mode

Agora é só rodar o comando para descriptografar os arquivos encontrados e listados:

  for (const auto& file : gpg_files) {
    std::string com = "gpg --yes --batch --passphrase=" + str + " " + file + " 2>/dev/null";
    std::cout << "Descriptografando: " << file << std::endl;
    std::system(com.data());
  }
Enter fullscreen mode Exit fullscreen mode

Eu ainda iria descompactar eles automaticamente adicionando ao loop, mas desisti, nesse caso usando o comando extract porque os tipos poderiam se variados: zip, rar, tar.gz,...

// filename se iguala a file para separar a lógica
std::string filename = file;

// Remover o .gpg do nome do arquivo
if (filename.size() >= 4) {
  filename = filename.substr(0, filename.size() - 4);
}

// Executar
std::string extract = "/usr/bin/extract " + filename;
std::cout << extract << std::endl;
std::system(extract.data());
Enter fullscreen mode Exit fullscreen mode

Eu desisti de fazer isso porque isso iria misturar minha tarefa específica, e depois cheguei até tentar, mas o resultado não foi tão bom.

O código completo ficou: decript.cpp

#include <iostream>
#include <filesystem>
#include <vector>

namespace fs = std::filesystem;

int main(){
  // Indicar o caminho da pasta, nesse caso, onde está o script
  std::string directory_path = "./";
  std::vector<std::string> gpg_files {};

  // Verificar se o diretório existe
  if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
    std::cerr << "O diretório não existe ou não válido." << std::endl;
    return 1;
  }

  // Iterar sobre os arquivos no diretório
  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());
    }
  }

  // Opcional
  // Exibe os nomes dos arquivos .gpg encontrados
  std::cout << "Arquivos .gpg encontrados:" << std::endl;
  for (const auto& file : gpg_files) {
    std::cout << file << ' ';
  }
  std::cout.put('\n');

  // Definir a senha para todos os arquivos
  std::string str = "SENHA_SECRETA";
}

Enter fullscreen mode Exit fullscreen mode

Se quiser fazer o mesmo script, mas para criar arquivos .gpg com senha dinamicamente, substitua com por:

std::string com = "gpg --yes --batch --passphrase=" + str + " -c " + file;
Enter fullscreen mode Exit fullscreen mode

Note o uso do -c.


Script final

decript.cpp

#include <iostream>
#include <filesystem>
#include <vector>

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 << "O diretório não existe ou não válido." << 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 << "Arquivos .gpg encontrados:" << std::endl;
  for (const auto& file : gpg_files) {
    std::cout << file << ' ';
  }
  std::cout << "\n\n";

  std::string str = "SENHA_SECRETA";

  for (const auto& file : gpg_files) {
    std::string com = "gpg --yes --batch --passphrase=" + str + " " + file + " 2>/dev/null";
    std::cout << "Descriptografando: " << file << std::endl;
    int run = std::system(com.data());
    if(run != 0){
      std::cerr << "Failed to run: " << com << std::endl;
    }
  }

  return EXIT_SUCCESS;
}
Enter fullscreen mode Exit fullscreen mode

Se quiser garantir que não há violação de memória, compile:

g++ -g -Wpedantic -Wall -Werror -fsanitize=address decript.cpp
Enter fullscreen mode Exit fullscreen mode

Mas, para rodar, adicione mais velocidade na execução:

g++ -Ofast decript.cpp
Enter fullscreen mode Exit fullscreen mode

Depois é só rodar: ./a.out.

Para extrair eu usei um script em 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("Descompactando: " + files[i])
  exec("extract " + files[i])
}
Enter fullscreen mode Exit fullscreen mode

Para mais informações sobre Terlang, conheça nosso Curso de Como Criar Sua Própria Linguagem de Programação:

https://terminalroot.com.br/mylang


E assim, eu fiz, do meu jeito, uma tarefa que poderia me levar muito tempo, de forma rápida e prática! 😃

Quadratic AI

Quadratic AI – The Spreadsheet with AI, Code, and Connections

  • AI-Powered Insights: Ask questions in plain English and get instant visualizations
  • Multi-Language Support: Seamlessly switch between Python, SQL, and JavaScript in one workspace
  • Zero Setup Required: Connect to databases or drag-and-drop files straight from your browser
  • Live Collaboration: Work together in real-time, no matter where your team is located
  • Beyond Formulas: Tackle complex analysis that traditional spreadsheets can't handle

Get started for free.

Watch The Demo 📊✨

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay