@extends('layouts.docs') @section('title', 'Segurança - OG Framework') @section('body')
Criptografia
O módulo de Security centraliza operações críticas de segurança do framework, fornecendo encriptação simétrica para dados sensíveis e gestão de tokens JWT para autenticação entre serviços.
O Security Module é a "caixa-forte" do framework. Sempre que precisas de proteger dados que vão ser armazenados (como tokens de terceiros, dados pessoais, ou credenciais de APIs externas), usas o Encrypter. Quando precisas de trocar informação autenticada entre serviços (como provar que um pedido veio realmente do ERP), usas o JwtManager.
Vamos ver cada um em detalhe.
Imagina que tens de guardar o token de acesso à API de um banco na base de dados. Se alguém aceder à base de dados, esse token não pode estar em texto limpo. O Encrypter resolve isto — encripta os dados com AES-256 antes de os guardar, e desencripta quando precisas de os usar.
A encriptação é "simétrica" porque usa a mesma chave (APP_KEY) para encriptar e desencriptar. É rápida e eficiente para dados que só a tua aplicação precisa de ler.
Uso Básico
A Facade Crypt torna isto muito simples. Podes encriptar strings, arrays, ou objectos — o Encrypter serializa tudo automaticamente.
use Og\Modules\Common\Facades\Crypt;
// Encriptar dados simples
$encrypted = Crypt::encrypt('token-secreto-do-banco');
// Encriptar arrays (serializados automaticamente)
$encrypted = Crypt::encrypt([
'access_token' => 'xxx',
'refresh_token' => 'yyy',
'expires_at' => now()->addHours(2)
]);
// Desencriptar
$data = Crypt::decrypt($encrypted);
echo $data['access_token']; // 'xxx'
Quando Usar?
Usa o Encrypter para proteger dados que a tua aplicação precisa de ler mais tarde. Exemplos típicos:
Nota: Para passwords de utilizadores, continua a usar hashing (bcrypt). O Encrypter é para dados que precisas de recuperar, não para validar.
Os JWTs são usados para provar identidade entre sistemas. Ao contrário do Encrypter, um JWT não esconde o conteúdo — qualquer pessoa pode ler o payload. O que garante é que o conteúdo não foi alterado e que foi emitido por quem diz ter sido.
No OfficeGest, usamos JWTs principalmente para comunicação com a Autoridade Tributária e outros sistemas externos que exigem assinaturas digitais.
Algoritmos Disponíveis
O algoritmo determina como a assinatura é criada. Os mais comuns:
Uso Básico
use Og\Modules\Common\Facades\Jwt;
// Criar um JWT assinado com RS256
$payload = [
'iss' => 'officegest.com', // Quem emitiu
'sub' => $user->getId(), // Sujeito (utilizador)
'iat' => time(), // Issued at
'exp' => time() + 3600, // Expira em 1 hora
'data' => ['nif' => '123456789']
];
$token = Jwt::encode($payload, $privateKey, 'RS256');
// Verificar e decodificar um JWT recebido
try {
$decoded = Jwt::decode($token, $publicKey, 'RS256');
echo $decoded->sub; // ID do utilizador
} catch (ExpiredException $e) {
// Token expirou
} catch (SignatureInvalidException $e) {
// Assinatura inválida — alguém alterou o token
}
Trabalhar com chaves RSA pode ser frustrante. Ficheiros exportados de diferentes sistemas vêm com formatações diferentes — alguns têm BOMs invisíveis, outros usam \r\n em vez de \n, e por aí fora. O JwtManager actua como um "médico de chaves" que corrige estes problemas automaticamente.
Normalização Automática
Quando passas uma chave ao encode() ou decode(), o JwtManager detecta e corrige automaticamente:
\n como texto em vez de quebras de linha reais — convertido.\r\n convertido para \n.Ofuscação de Chaves
Para alguns cenários (como integração com a AT), precisamos de guardar chaves RSA na base de dados. Em vez de as guardar em texto limpo, podemos ofuscá-las.
// Ofuscar uma chave antes de guardar na BD
$obfuscated = Jwt::encodeRsaKey($privateKey);
// Guardar $obfuscated na base de dados...
// Restaurar quando precisar de usar
$privateKey = Jwt::decodeRsaKey($obfuscated);
$token = Jwt::encode($payload, $privateKey);
A APP_KEY é a chave mestra do Encrypter. Sem ela, nada funciona. Deve ser uma string de 32 bytes codificada em base64, começando com base64:.
Gerar uma Nova Chave
Usa o comando CLI. A chave é gerada e automaticamente guardada no ficheiro de configuração.
docker compose exec app php og key:generate
⚠️ Nunca Partilhes a APP_KEY
A APP_KEY é como a chave mestra de um cofre. Se alguém a obtiver, pode desencriptar todos os dados protegidos. Nunca a comitas em repositórios git, nunca a partilhes em logs ou mensagens. Cada ambiente (local, staging, produção) deve ter a sua própria chave.
"Unsupported cipher or incorrect key length"
Este erro significa que a APP_KEY está mal formatada. Verifica que:
base64:base64: tem exactamente 44 caracteres (que decodificam para 32 bytes)"JWT Signature Verification Failed"
Estás a usar a chave errada para verificar. Lembra-te: