As informações guardadas no banco de dados geralmente têm um valor enorme pra empresa. Mas, infelizmente, elas também são super atrativas pra quem quer fazer coisa errada. Por isso é importante pensar em criptografia — é um dos jeitos de proteger os dados de olhares curiosos.
A criptografia ajuda a proteger informações confidenciais: tipo senhas, números de cartão de crédito ou dados pessoais. Também ajuda a seguir leis como GDPR ou HIPAA. E se rolar algum vazamento, os dados criptografados vão estar bem menos vulneráveis, o que diminui o prejuízo.
No PostgreSQL tem funções bem práticas pra criptografia simétrica. Com pgp_sym_encrypt(data, key) você pode criptografar os dados que quiser, e depois descriptografar com pgp_sym_decrypt(encrypted_data, key), usando a mesma chave. É simples — e seguro.
Exemplo de criptografia de dados
Passo 1: Criando a tabela
Vamos criar uma tabela users com uma coluna pra guardar números de telefone criptografados:
-- Criando tabela com coluna pra guardar dados criptografados
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
phone_encrypted BYTEA -- Aqui vão ficar os números de telefone criptografados
);
Passo 2: Adicionando dados com criptografia
Agora vamos adicionar um usuário, criptografando o número de telefone dele:
-- Inserindo dados com criptografia
INSERT INTO users (username, phone_encrypted)
VALUES ('john_doe', pgp_sym_encrypt('123-456-7890', 'my_secret_key'));
Repara no uso da função pgp_sym_encrypt. my_secret_key é a nossa chave simétrica. Na vida real, a chave tem que ser bem difícil e super protegida.
Passo 3: Buscando dados com descriptografia
Quando precisar acessar os dados, dá pra descriptografar assim:
-- Buscando dados com descriptografia
SELECT
username,
pgp_sym_decrypt(phone_encrypted, 'my_secret_key') AS phone
FROM users;
Se a chave estiver certa, você vai ver o número de telefone original.
Deixando mais avançado: adicionando criptografia em tabela já existente
E se a tabela já existe e a gente quer começar a criptografar uma das colunas? Bora ver como faz.
Passo 1: Criando uma nova coluna
Imagina que temos uma tabela customers e queremos criptografar as colunas com números de cartão de crédito:
-- Adicionando nova coluna pra dados criptografados
ALTER TABLE customers ADD COLUMN card_number_encrypted BYTEA;
Passo 2: Migrando dados pra coluna criptografada
A gente criptografa os dados que já existem e coloca na nova coluna:
-- Criptografando dados e migrando pra nova coluna
UPDATE customers
SET card_number_encrypted = pgp_sym_encrypt(card_number, 'my_other_secret_key');
Passo 3: Removendo a coluna não criptografada
Depois que tudo estiver criptografado, pode apagar a coluna antiga:
-- Removendo a coluna antiga não criptografada
ALTER TABLE customers DROP COLUMN card_number;
Agora os dados estão protegidos por criptografia e só dá pra acessar com a chave certa.
Particularidades de trabalhar com dados criptografados
Tem uns pontos importantes quando você trabalha com colunas criptografadas:
Tipo de dado:
- Os valores criptografados ficam em formato binário (
BYTEA), não dá pra ler direto. - Pra consultar, tem que usar as funções de descriptografia.
Busca e filtragem:
- Não dá pra buscar linhas direto pelo dado criptografado, tipo:
SELECT * FROM users WHERE phone_encrypted = '123-456-7890'; -- NÃO VAI FUNCIONAR!
- Em vez disso, dá pra descriptografar na consulta:
SELECT *
FROM users
WHERE pgp_sym_decrypt(phone_encrypted, 'my_secret_key') = '123-456-7890';
Performance:
Criptografar e descriptografar pode deixar as consultas mais lentas. Usa só onde for realmente necessário.
Cenário real: protegendo senhas
Guardar senhas é uma das tarefas mais comuns de criptografia. Em vez de guardar senha em texto puro (péssima ideia), tem que fazer hash delas.
Fazendo hash da senha usando pgcrypto
Vamos usar a função crypt() pra fazer hash seguro das senhas:
-- Fazendo hash da senha ao inserir registro
INSERT INTO users (username, phone_encrypted)
VALUES ('alice', crypt('my_secure_password', gen_salt('bf')));
Aqui o gen_salt('bf') cria um salt pra fazer o hash da senha.
Pra checar a senha, é só comparar o hash:
-- Comparando senha com hash
SELECT username
FROM users
WHERE crypt('my_secure_password', phone_encrypted) = phone_encrypted;
Dicas de segurança
- Guarde as chaves separadas:
Nunca salve as chaves simétricas no mesmo banco de dados dos dados criptografados.
- Use chaves difíceis:
Chaves simples tipo "123" são fáceis de adivinhar.
- Troque as chaves regularmente:
Pra evitar vazamentos, é bom trocar as chaves de vez em quando e recriptografar os dados.
GO TO FULL VERSION