Desencriptação pelo Python - Tabela para Planilha

PostgreSQL no Raspberry Pi com FreeBSD 13

Planilha recuperada.ods aberta no OpenOffice Calc
Planilha recuperada.ods aberta no OpenOffice Calc

Em Encriptação pelo Python - Planilha para Tabela foi visto como armazenar com segurança numa tabela do PostgreSQL, com as informações encriptadas usando a biblioteca cryptography do Python, os dados das contas de vários sites contidos numa planilha. Agora vamos ver como recuperar as informações armazenadas na tabela e recriar a planilha contendo estas informações.

As definições para conexão do programa Python com o servidor de banco de dados estão mostradas em Módulo Python libpostgres, os parâmetros para conexão com o servidor de banco de dados são os mesmos mostrados em Encriptação - Chave Simétrica - Planilha para Tabela, e a criação da chave está mostrada em Geração da chave de criptografia

Planilha OpenDocument

Os dados das contas lidos na tabela do banco de dados são escritos na planilha recuperada.ods, no formato especificado pelo Open Document Format for Office Applications (ODF), podendo ser abertas pelo Apache OpenOffice Calc, como mostrado na imagem acima, ou por outras planilhas que trabalham com este formato.

Programa

Abaixo está mostrado o programa que lê os dados da tabela sites no servidor de banco de dados PostgreSQL e cria a planilha recuperada.ods.

#!/usr/bin/env ipython
# -*- coding: utf-8 -*-
"""Criptografia pelo Usuário - Fernet - Tabela para Planilha.

Este programa lê em uma tabela do PostgreSQL os dados encriptados
das contas de vários sites, desencripta-os, e cria com estes dados
desencriptados uma planilha OpenDocument.

A senha de desencriptação é lida do terminal ou da console.
Se não for lida de um terminal pode ser exibida na tela.

"""

import re
from pyexcel_ods3 import save_data
import textwrap
import psycopg2
from cryptography.fernet import Fernet
import getpass
import libpostgres

# Comando SQL para ler as linhas do usuário na tabela
SQLSEL = textwrap.dedent("""\
    SELECT id, login, titulo, url, usuario, senha, notas
    FROM vis_user_sites
    ORDER BY titulo
""")


def ler(conn, fernet):
    """Lê as linhas da planilha na tabela e as desencripta

    Args:
        conn: Objeto de conexão com o servidor de banco de dados.
        fernet: Objeto de encriptação simétrica.

    Returns:
        Linhas da tabela desencriptadas

    """
    dados = [['titulo', 'url', 'usuario', 'senha', 'notas']]
    try:
        cur = conn.cursor()
        cur.execute(SQLSEL)
        linhas = cur.fetchall()
        for linha in linhas:
            celulas = list(linha)
            pk = celulas[0]
            login = celulas[1]
            titulo = celulas[2]
            url = fernet.decrypt(celulas[3].tobytes()).decode()
            usuario = fernet.decrypt(celulas[4].tobytes()).decode()
            senha = fernet.decrypt(celulas[5].tobytes()).decode()
            notas = fernet.decrypt(celulas[6].tobytes()).decode()
            print(pk, login, titulo, url, usuario, senha, notas)
            dados.append([titulo, url, usuario, senha, notas, ])
    except (Exception, psycopg2.DatabaseError) as e:
        print(e)

    print(dados)
    return dados


if __name__ == '__main__':
    # Ler a senha na console
    key = getpass.getpass(prompt="Forneça a chave para desencriptação: ")
    # Ficar somente com a parte entre ''
    key = re.findall("(?<=\')(.*?)(?=\')", key)
    # Objeto de encriptação simétrica
    fernet = Fernet(bytes(key[0], 'utf-8'))
    # Obter os parâmetros da conexão no arquivo de configuração
    parametros = libpostgres.config(secao='halley')
    login = parametros["user"]
    # Conectar com o servidor de banco de dados
    conn = libpostgres.conectar(parametros)
    # Ler os dados da tabela e criar a planilha
    linhas = ler(conn, fernet)
    planilha = {"Sheet1": linhas}
    print(planilha)
    save_data("recuperada.ods", planilha)
    # Fechar a conexão com o servidor de banco de dados
    conn.close()

Abaixo está mostrada a saída produzida pelo programa:

Warning: Password input may be echoed.
Forneça a chave para desencriptação: b'JvNU1GfIsnIU4vkVi2UqN9218SWhUe0u9KDFwgHEDOQ='
Conectado ao PostgreSQL
1 halley Google https://www.google.com.br/ usuario_google senha_google Site de busca, e-mail,...
4 halley Priberam https://dicionario.priberam.org/   Dicionário de Português Contemporâneo
5 halley ProtonMail https://mail.protonmail.com/l usuario_proton senha_proton E-mail
3 halley Wikipédia https://pt.wikipedia.org/ usuario_wikipedia senha_wikipedia Enciclopédia livre
2 halley Yahoo https://br.yahoo.com/ usuario_yahoo senha_yahoo Site de busca, e-mail, finanças, …
[['titulo', 'url', 'usuario', 'senha', 'notas'], ['Google', 'https://www.google.com.br/', 'usuario_google', 'senha_google', 'Site de busca, e-mail,...'], ['Priberam', 'https://dicionario.priberam.org/', '', '', 'Dicionário de Português Contemporâneo'], ['ProtonMail', 'https://mail.protonmail.com/l', 'usuario_proton', 'senha_proton', 'E-mail'], ['Wikipédia', 'https://pt.wikipedia.org/', 'usuario_wikipedia', 'senha_wikipedia', 'Enciclopédia livre'], ['Yahoo', 'https://br.yahoo.com/', 'usuario_yahoo', 'senha_yahoo', 'Site de busca, e-mail, finanças, …']]
{'Sheet1': [['titulo', 'url', 'usuario', 'senha', 'notas'], ['Google', 'https://www.google.com.br/', 'usuario_google', 'senha_google', 'Site de busca, e-mail,...'], ['Priberam', 'https://dicionario.priberam.org/', '', '', 'Dicionário de Português Contemporâneo'], ['ProtonMail', 'https://mail.protonmail.com/l', 'usuario_proton', 'senha_proton', 'E-mail'], ['Wikipédia', 'https://pt.wikipedia.org/', 'usuario_wikipedia', 'senha_wikipedia', 'Enciclopédia livre'], ['Yahoo', 'https://br.yahoo.com/', 'usuario_yahoo', 'senha_yahoo', 'Site de busca, e-mail, finanças, …']]}

* * *