Aviso importante — leia antes de usar
Este repositório contém um protótipo educativo para cifrar arquivos e diretórios de forma não destrutiva. Ele foi projetado para fins de aprendizado, testes e backups privados. Não use este código para ações furtivas, destrutivas ou sem o consentimento explícito dos donos dos dados.
gcry_batch_insane.py é um utilitário CLI que cria cópias cifradas de arquivos (extensão .gcry) a partir de um arquivo ou pasta. Ele combina várias funcionalidades avançadas ("insanas") de forma segura e explícita:
- Criptografia por arquivo com
file_key(chave simétrica única por arquivo). - Proteção da
file_keypor senha (PBKDF2-HMAC-SHA256) e por recipients (RSA-OAEP) — opcional. - Modo proprietário: header cifrado com uma chave da aplicação (
APP_SECRET) para que apenas seu interpretador/cliente possa ler metadados (opcional). - Compressão streaming (gzip) para reduzir tamanho antes da cifragem.
- Suporte a AES-256-GCM (padrão) e XChaCha20-Poly1305 (se disponível na sua versão do
cryptography). - Assinatura Ed25519 do header (opcional) para autenticidade.
- Ofuscação determinística do nome do ficheiro no header (opcional).
- Framing por chunk (cada bloco cifrado é escrito com prefixo
uint32_be(length)), permitindo streaming fiável. - Modo
--dry-run,--force,--in-file/--out-file,--in-dir/--out-dir,--mark-hidden(aplica apenas se explicitamente pedido), geração demanifest.json.
Requisitos: Python 3.8+ e biblioteca cryptography.
pip install cryptographySe quiser usar XChaCha20-Poly1305, certifique-se de que sua versão da biblioteca cryptography o suporte.
Layout do ficheiro:
MAGIC (8 bytes: b'GCRYFILE')
header_length (4 bytes big-endian)
header_json (N bytes) # pode ser *proprietary* (cifrado)
sequence of framed chunks: # cada chunk: uint32_be(len) || cipher_chunk
uint32_be(len_chunk)
cipher_chunk (len_chunk bytes)
O header_json pode conter, entre outros campos:
proprietary: true/false — se true, header contémapp_salt,header_ct,header_nonce(inner header cifrado);payload_nonce_base: base de 8 bytes usada com um contador (4 bytes BE) para gerar nonces de 12 bytes por chunk;file_key_wrapped_by_kekewrap_nonce(se a proteção por senha foi usada);recipients(lista comwrapped_keypara cada recipient — RSA-OAEP);compress,cipher,chunk_size,obfuscated_filename(se aplicado),signature(Ed25519) etc.
python gcry_batch_insane.py --in-file .\text.txt --out-file .\text.txt.gcry --password "senha" --app-secret "MINHA_APP_SECRET" --obfuscatepython gcry_batch_insane.py --in-dir .\input_dir --out-dir .\encrypted_output --dry-run --compresspython gcry_batch_insane.py --in-dir .\input_dir --out-dir .\encrypted_output --password "senha" --app-secret "MINHA_APP_SECRET"Para pular a confirmação interativa use --force (use com cuidado).
Use o script gcry_prototype.py ou a função de decrypt integrada. Exemplo com gcry_prototype.py:
python gcry_prototype.py decrypt .\encrypted_output\text.txt.gcry .\recovered_text.txtSe o arquivo for proprietary (header cifrado com APP_SECRET) você precisa fornecer APP_SECRET ao interpretar (via --app-secret ou variável de ambiente GCRY_APP_SECRET).
--in-file/--out-file— encripta um único arquivo.--in-dir/--out-dir— encripta recursivamente uma pasta.--password/-p— senha para derivar KEK (PBKDF2).--recipients— lista separada por vírgula de PEMs RSA public para wrapping.--priv-keys— PEMs RSA privados para descriptografar recipients.--sign-key/--verify-key— Ed25519 PEM para assinar/validar header.--cipher—aes(padrão) ouchacha(XChaCha20-Poly1305 se disponível).--compress— ativar compressão streaming (gzip format).--dry-run— apenas simula as operações, não escreve saída.--force— pula a confirmação interativa.--obfuscate— ofusca (cifra) o nome original no header.--mark-hidden— marca o ficheiro resultante como oculto (aplica somente se explicitamente pedido).--app-secret— fornece o segredo da aplicação (opcional; também pode ser passado pela variável de ambienteGCRY_APP_SECRET).
Quando --app-secret é fornecido (ou via GCRY_APP_SECRET), o script faz o seguinte:
- Deriva
APP_KEKa partir deAPP_SECRETusando HKDF (salt gerado por arquivo). - Constrói um
header_innercom salts, recipients, payload_nonce_base, etc. - Cifra
header_innercomAPP_KEK(AES-GCM) produzindoheader_cteheader_nonce. - Armazena no
header_jsonexterno apenas os campos necessários para o interpretador recuperar oheader_inner(app_salt,header_ct,header_nonce) e marca o arquivo comoproprietary.
Sem APP_SECRET, outras ferramentas não conseguem recuperar payload_nonce_base, salts ou wrapped keys, o que impede a maioria das tentativas de descriptografia por ferramentas genéricas.
Limitação importante: se você embutir APP_SECRET no cliente que distribui, um atacante com acesso ao binário poderá eventualmente extrair esse segredo. Para uma proteção real, use KMS/attestation/HSM.
- Não invente suas próprias primitivas criptográficas — este projeto usa primitives da biblioteca
cryptography(AES-GCM, XChaCha20-Poly1305, PBKDF2, RSA-OAEP, Ed25519). - Senhas fracas são suscetíveis a força bruta — o uso de PBKDF2 com altos
kek_itersajuda, mas considere Argon2id para produção. - Nonces exclusivos: o esquema usa
payload_nonce_base || counterpara nonces por chunk. Não reutilizepayload_nonce_basecom a mesmafile_keyem outro arquivo. - APP_SECRET embutido não é invulnerável — para confidencialidade real, use KMS/HSM ou um servidor que libere chaves sob políticas.
- Mantém backups das chaves/senhas — perda irreversível causa perda dos dados.
- Sempre faça
dry-runantes de executar em produção. - Teste roundtrip: encriptar -> descriptografar e comparar checksums (SHA256).
- Teste alteração: corrompa um byte no
.gcrye verifique que a descriptografia falha (tamper detection via AEAD).
Este protótipo é fornecido para fins educacionais. Use por sua conta e risco. Não me responsabilizo por usos indevidos.
- Uso de Argon2id em vez de PBKDF2 (melhor resistência a GPU/ASIC).
- Integração com KMS para armazenamento/rotacão de
APP_SECRET. - Empacotar e ofuscar o cliente para dificultar engenharia reversa (não é substituto para KMS).
- UI/CLI com barra de progresso e logs detalhados.