Como criptografar com Python: Um guia completo sobre como usar a biblioteca cryptography

Para proteger dados de forma segura em Python, a criptografia eficaz é essencial. Neste artigo, vamos explicar em detalhes como usar a poderosa biblioteca de criptografia do Python, a cryptography, desde os métodos básicos de criptografia até exemplos avançados. A explicação será feita de forma passo a passo, para que até iniciantes possam entender, e forneceremos exercícios práticos e exemplos de projetos para promover uma compreensão mais profunda. Através deste artigo, você aprenderá os fundamentos da segurança de dados e adquirirá habilidades práticas para aplicá-las.

Índice

Como instalar a biblioteca cryptography

A primeira etapa para realizar criptografia em Python é instalar a biblioteca cryptography. A seguir, mostramos como instalá-la facilmente através de um simples passo a passo.

Preparação do ambiente

Certifique-se de que o Python está instalado e que você possui a ferramenta de gerenciamento de pacotes necessária (pip) instalada.

Verificação da instalação do Python

Abra o terminal ou o prompt de comando e execute o seguinte comando para verificar se o Python está instalado:

python --version

Verificação da instalação do pip

Para verificar se o pip está instalado, execute o seguinte comando:

pip --version

Instalação da biblioteca cryptography

Utilize o pip para instalar a biblioteca cryptography. Execute o seguinte comando no terminal ou prompt de comando:

pip install cryptography

Verificação da instalação

Para verificar se a instalação foi bem-sucedida, abra o interpretador Python e execute o seguinte comando:

import cryptography
print(cryptography.__version__)

Se a instalação for bem-sucedida, o número da versão será exibido. Agora você tem a biblioteca cryptography instalada.

Fundamentos da criptografia simétrica

A criptografia simétrica é um método de criptografia que utiliza a mesma chave tanto para a criptografia quanto para a descriptografia dos dados. Aqui, vamos apresentar como usar a biblioteca cryptography para implementar a criptografia simétrica.

O que é criptografia simétrica?

A criptografia simétrica utiliza uma única chave para criptografar os dados e, posteriormente, a mesma chave é usada para descriptografá-los. Por isso, a gestão da chave é essencial. Um exemplo de criptografia simétrica é o AES (Advanced Encryption Standard).

Criptografia e descriptografia com AES

A seguir, vamos explicar como criptografar e descriptografar dados utilizando o AES.

Importação dos módulos necessários

Primeiro, importamos os módulos necessários da biblioteca cryptography.

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
import os

Geração da chave e vetor de inicialização (IV)

Para criptografar com AES, precisamos de uma chave e um vetor de inicialização (IV). Vamos gerar ambos.

key = os.urandom(32)  # Chave de 256 bits
iv = os.urandom(16)   # Vetor de inicialização de 128 bits

Preenchimento dos dados

Em criptografia de blocos, os dados precisam ser múltiplos do tamanho do bloco. Vamos adicionar preenchimento aos dados.

def pad(data):
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    return padder.update(data) + padder.finalize()

Criptografia

A seguir, criptografamos os dados.

def encrypt(data, key, iv):
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    padded_data = pad(data)
    return encryptor.update(padded_data) + encryptor.finalize()

Descriptografia

Agora, vamos descriptografar os dados criptografados.

def decrypt(encrypted_data, key, iv):
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    padded_data = decryptor.update(encrypted_data) + decryptor.finalize()
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    return unpadder.update(padded_data) + unpadder.finalize()

Exemplo prático

No exemplo abaixo, vamos criptografar e descriptografar uma mensagem de texto.

data = b"Esta é uma mensagem secreta"
encrypted_data = encrypt(data, key, iv)
print("Dados criptografados:", encrypted_data)

decrypted_data = decrypt(encrypted_data, key, iv)
print("Dados descriptografados:", decrypted_data.decode())

Assim, podemos usar a biblioteca cryptography para implementar criptografia simétrica e proteger dados.

Fundamentos da criptografia assimétrica

A criptografia assimétrica utiliza chaves diferentes para criptografar e descriptografar dados. Aqui, vamos explicar como usar a biblioteca cryptography para implementar criptografia assimétrica.

O que é criptografia assimétrica?

A criptografia assimétrica utiliza um par de chaves: uma chave pública para criptografar os dados e uma chave privada para descriptografá-los. Apenas a chave privada pode descriptografar os dados criptografados com a chave pública correspondente. Este método é amplamente usado para troca segura de dados. O RSA (Rivest-Shamir-Adleman) é um exemplo comum.

Criptografia e descriptografia com RSA

A seguir, vamos explicar como criptografar e descriptografar dados utilizando o RSA.

Importação dos módulos necessários

Primeiro, importamos os módulos necessários da biblioteca cryptography.

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding

Geração do par de chaves

Agora, vamos gerar o par de chaves (pública e privada) para criptografia com RSA.

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

Armazenamento e leitura das chaves

Agora vamos mostrar como salvar as chaves em arquivos e lê-las posteriormente.

# Salvando a chave privada
private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)

# Salvando a chave pública
public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)

# Lendo as chaves
loaded_private_key = serialization.load_pem_private_key(private_pem, password=None)
loaded_public_key = serialization.load_pem_public_key(public_pem)

Criptografia

Agora vamos criptografar os dados utilizando a chave pública.

def encrypt(data, public_key):
    return public_key.encrypt(
        data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

Descriptografia

Agora vamos descriptografar os dados utilizando a chave privada.

def decrypt(encrypted_data, private_key):
    return private_key.decrypt(
        encrypted_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

Exemplo prático

Agora vamos criptografar e descriptografar uma mensagem de texto utilizando RSA.

data = b"Esta é uma mensagem secreta"
encrypted_data = encrypt(data, public_key)
print("Dados criptografados:", encrypted_data)

decrypted_data = decrypt(encrypted_data, private_key)
print("Dados descriptografados:", decrypted_data.decode())

Assim, podemos usar a biblioteca cryptography para implementar criptografia assimétrica e garantir a segurança da comunicação de dados.

Fundamentos de hash

O hashing é um método de transformar dados em um valor de comprimento fixo, conhecido como hash. Este valor é unidirecional, ou seja, não é possível reverter o hash para obter os dados originais. Aqui, vamos explicar como usar a biblioteca cryptography para aplicar o hashing.

O que é hashing?

O hashing é utilizado para verificar a integridade dos dados e armazenar senhas de forma segura. Um exemplo de algoritmo de hash é o SHA-256 (Secure Hash Algorithm 256-bit).

Hashing com SHA-256

A seguir, vamos explicar como gerar um hash de dados utilizando o algoritmo SHA-256.

Importação dos módulos necessários

Primeiro, importamos os módulos necessários da biblioteca cryptography.

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend

Hashing dos dados

A seguir, vamos aplicar o algoritmo SHA-256 para gerar o hash de dados.

def hash_data(data):
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(data)
    return digest.finalize()

Exemplo prático

No exemplo abaixo, vamos gerar um hash de uma mensagem de texto.

data = b"Este é o dado a ser hashado"
hashed_data = hash_data(data)
print("Dado hashado:", hashed_data.hex())

Exemplo de uso do valor hash

Os valores de hash podem ser usados para verificar a integridade dos dados. Por exemplo, após baixar um arquivo, você pode comparar o valor hash para garantir que os dados não foram corrompidos.

# Exemplo de cálculo do hash de um arquivo
def hash_file(file_path):
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    with open(file_path, 'rb') as f:
        while chunk := f.read(8192):
            digest.update(chunk)
    return digest.finalize()

# Calculando e exibindo o hash do arquivo
file_path = 'path/to/your/file'
file_hash = hash_file(file_path)
print("Hash do arquivo:", file_hash.hex())

Com isso, podemos usar a biblioteca cryptography para aplicar hashing e verificar a integridade dos dados. O hashing é uma ferramenta importante para armazenar senhas e garantir a integridade dos dados.

Geração de chaves pública e privada

Gerar um par de chaves pública e privada é um passo essencial para a criptografia assimétrica. Aqui, vamos mostrar como gerar, salvar e ler as chaves usando a biblioteca cryptography.

Geração de pares de chaves RSA

Usando o algoritmo RSA, vamos gerar um par de chaves pública e privada.

Importação dos módulos necessários

Primeiro, importamos os módulos necessários da biblioteca cryptography.

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

Geração do par de chaves

Agora, vamos gerar o par de chaves RSA.

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

Armazenamento das chaves

Agora, vamos salvar as chaves em arquivos. As chaves privada e pública serão armazenadas separadamente.

# Salvando a chave privada
with open("private_key.pem", "wb") as private_file:
    private_file.write(private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ))

# Salvando a chave pública
with open("public_key.pem", "wb") as public_file:
    public_file.write(public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ))

Leitura das chaves

Agora, vamos ler as chaves de volta dos arquivos salvos.

# Lendo a chave privada
with open("private_key.pem", "rb") as private_file:
    loaded_private_key = serialization.load_pem_private_key(
        private_file.read(),
        password=None,
    )

# Lendo a chave pública
with open("public_key.pem", "rb") as public_file:
    loaded_public_key = serialization.load_pem_public_key(
        public_file.read()
    )

Exemplo prático

A seguir, vamos usar o par de chaves para criptografar e descriptografar dados.

from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

# Criptografia de dados
def encrypt(data, public_key):
    return public_key.encrypt(
        data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

# Descriptografia de dados
def decrypt(encrypted_data, private_key):
    return private_key.decrypt(
        encrypted_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

# Exemplo de criptografia e descriptografia
data = b"Esta é uma mensagem secreta"
encrypted_data = encrypt(data, loaded_public_key)
print("Dados criptografados:", encrypted_data)

decrypted_data = decrypt(encrypted_data, loaded_private_key)
print("Dados descriptografados:", decrypted_data.decode())

Assim, usando a biblioteca cryptography, podemos gerar, armazenar e usar chaves públicas e privadas para criptografar e descriptografar dados de maneira segura.

Criptografia e descriptografia prática

Agora vamos ver, na prática, como criptografar e descriptografar dados utilizando a biblioteca cryptography, tanto com criptografia simétrica (AES) quanto assimétrica (RSA).

Criptografia e descriptografia com criptografia simétrica

Importação dos módulos necessários

Primeiro, importamos os módulos necessários para a criptografia simétrica.

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
import os

Geração da chave e do vetor de inicialização (IV)

Geramos a chave e o vetor de inicialização (IV) para criptografia AES.

key = os.urandom(32)  # Chave de 256 bits
iv = os.urandom(16)   # Vetor de inicialização de 128 bits

Preenchimento dos dados

Adicionamos preenchimento aos dados para garantir que fiquem em múltiplos do tamanho do bloco.

def pad(data):
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    return padder.update(data) + padder.finalize()

Criptografia dos dados

Agora, criptografamos os dados com a chave e o vetor de inicialização gerados.

def encrypt(data, key, iv):
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    padded_data = pad(data)
    return encryptor.update(padded_data) + encryptor.finalize()

Descriptografia dos dados

Descriptografamos os dados criptografados e removemos o preenchimento.

def decrypt(encrypted_data, key, iv):
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    padded_data = decryptor.update(encrypted_data) + decryptor.finalize()
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    return unpadder.update(padded_data) + unpadder.finalize()

Exemplo prático

Vamos criptografar e descriptografar uma mensagem de texto no próximo exemplo.

data = b"Esta é uma mensagem secreta"
encrypted_data = encrypt(data, key, iv)
print("Dados criptografados:", encrypted_data)

decrypted_data = decrypt(encrypted_data, key, iv)
print("Dados descriptografados:", decrypted_data.decode())

Criptografia e descriptografia com criptografia assimétrica

Importação dos módulos necessários

Agora vamos importar os módulos necessários para a criptografia assimétrica.

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding

Geração do par de chaves

Geramos o par de chaves RSA para criptografia assimétrica.

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

Criptografia e descriptografia

Vamos criptografar e descriptografar os dados usando o RSA.

def encrypt(data, public_key):
    return public_key.encrypt(
        data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

def decrypt(encrypted_data, private_key):
    return private_key.decrypt(
        encrypted_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

# Exemplo de criptografia e descriptografia
data = b"Esta é uma mensagem secreta"
encrypted_data = encrypt(data, public_key)
print("Dados criptografados:", encrypted_data)

decrypted_data = decrypt(encrypted_data, private_key)
print("Dados descriptografados:", decrypted_data.decode())

Com isso, você pode implementar criptografia e descriptografia com a biblioteca cryptography em seus projetos. Agora, vamos ver exemplos práticos e exercícios para aplicar essas técnicas.

Conclusão

Neste artigo, exploramos os fundamentos e as práticas de criptografia usando a biblioteca cryptography em Python. Você aprendeu como usar criptografia simétrica (AES), criptografia assimétrica (RSA) e hashing (SHA-256) em seus projetos. Com esses conhecimentos, você estará mais preparado para implementar soluções de segurança de dados em seus sistemas. A criptografia é um dos pilares da segurança digital e dominar essas técnicas é essencial para proteger dados de maneira eficaz.

Exemplos aplicados e exercícios

Agora, vamos apresentar exemplos aplicados e exercícios para que você possa aprimorar ainda mais seus conhecimentos na utilização da biblioteca cryptography. Estes exemplos ajudarão você a consolidar a compreensão da criptografia e a usá-la em projetos reais.

Exemplo 1: Aplicativo de chat criptografado

Para garantir a troca segura de mensagens, vamos mostrar como implementar um aplicativo de chat onde as mensagens são criptografadas antes de serem enviadas e descriptografadas ao serem recebidas.

Criptografando e descriptografando mensagens

No aplicativo de chat, a mensagem enviada precisa ser criptografada, e a mensagem recebida precisa ser descriptografada para garantir a segurança da comunicação.

# Função para criptografar a mensagem
def encrypt_message(message, public_key):
    return encrypt(message.encode(), public_key)

# Função para descriptografar a mensagem
def decrypt_message(encrypted_message, private_key):
    return decrypt(encrypted_message, private_key).decode()

# Exemplo de uso
message = "Olá, esta é uma mensagem secreta"
encrypted_message = encrypt_message(message, public_key)
print("Mensagem criptografada:", encrypted_message)

decrypted_message = decrypt_message(encrypted_message, private_key)
print("Mensagem descriptografada:", decrypted_message)

Exemplo 2: Sistema seguro de compartilhamento de arquivos

Agora, vamos mostrar como implementar um sistema seguro de compartilhamento de arquivos. O arquivo será criptografado antes de ser compartilhado e, quando recebido, será descriptografado.

Criptografando e descriptografando arquivos

O arquivo será criptografado antes de ser compartilhado e descriptografado ao ser aberto pelo destinatário.

# Função para criptografar o arquivo
def encrypt_file(file_path, key, iv):
    with open(file_path, 'rb') as file:
        file_data = file.read()
    encrypted_data = encrypt(file_data, key, iv)
    with open(file_path + '.enc', 'wb') as file:
        file.write(encrypted_data)

# Função para descriptografar o arquivo
def decrypt_file(encrypted_file_path, key, iv):
    with open(encrypted_file_path, 'rb') as file:
        encrypted_data = file.read()
    decrypted_data = decrypt(encrypted_data, key, iv)
    with open(encrypted_file_path.replace('.enc', ''), 'wb') as file:
        file.write(decrypted_data)

# Exemplo de uso
encrypt_file('shared_document.pdf', key, iv)
decrypt_file('shared_document.pdf.enc', key, iv)

Exercícios

Para ajudar você a consolidar seus conhecimentos, preparamos alguns exercícios práticos. Esses exercícios irão testar sua capacidade de aplicar os conceitos de criptografia em diferentes cenários.

Exercício 1: Implementação de um sistema de gerenciamento de senhas com criptografia simétrica

Crie um sistema para criptografar e armazenar as senhas dos usuários, utilizando criptografia simétrica (AES). O sistema deve ser capaz de criptografar uma senha ao armazená-la e descriptografá-la quando necessário.

  1. Crie uma função para criptografar a senha utilizando AES.
  2. Armazene a senha criptografada de forma segura.
  3. Crie uma função para descriptografar a senha ao ser acessada.

Exercício 2: Implementação de um sistema seguro de envio de mensagens com criptografia assimétrica

Utilize criptografia assimétrica para criar um sistema de envio seguro de mensagens. O sistema deve permitir que uma mensagem seja criptografada com a chave pública e, posteriormente, descriptografada com a chave privada.

  1. Gere um par de chaves pública e privada para criptografar e descriptografar a mensagem.
  2. Crie uma função para criptografar a mensagem usando a chave pública.
  3. Crie uma função para descriptografar a mensagem utilizando a chave privada.

Exercício 3: Implementação de um sistema de detecção de alterações de arquivos com hashing

Utilize hashing para implementar um sistema de detecção de alterações de arquivos. O sistema deve calcular o hash de um arquivo e permitir que você verifique se o arquivo foi alterado ao recalcular o hash após modificações.

  1. Crie uma função para calcular o hash de um arquivo usando SHA-256.
  2. Recalcule o hash de um arquivo após modificações e verifique se houve alguma alteração.

Através desses exercícios, você terá uma compreensão mais sólida de como usar a biblioteca cryptography para resolver problemas de segurança de dados em projetos reais.

Conclusão

Neste artigo, exploramos os fundamentos da criptografia utilizando a biblioteca cryptography em Python, cobrindo desde criptografia simétrica e assimétrica até hashing. Além disso, apresentamos exemplos práticos de como aplicar esses conceitos em projetos reais, como sistemas de gerenciamento de senhas, aplicativos de chat seguros e sistemas de compartilhamento de arquivos. Por meio de exercícios aplicados, você poderá reforçar sua compreensão e aplicar a criptografia de forma eficaz em suas aplicações. À medida que a segurança de dados se torna cada vez mais importante, dominar essas técnicas ajudará a proteger informações valiosas em seus projetos.

Índice