Autenticación HMAC
Guía completa de autenticación HMAC-SHA256 para la API
Autenticación HMAC-SHA256
La API de Legal Cookies utiliza autenticación HMAC-SHA256 para garantizar la seguridad e integridad de cada request. Este método es más seguro que enviar el API Secret directamente, ya que el secreto nunca viaja por la red.
Credenciales necesarias
| Credencial | Formato | Descripción |
|---|---|---|
| API Key | lc_pk_... | Identificador público de tu cuenta |
| API Secret | String de 48 caracteres | Clave secreta para firmar requests |
Importante: El API Secret solo se muestra una vez al aprobar tu cuenta. Guárdalo en un lugar seguro.
Headers requeridos
Cada request debe incluir estos headers:
| Header | Descripción |
|---|---|
X-Api-Key | Tu API Key |
X-Timestamp | Unix timestamp en milisegundos |
X-Signature | Firma HMAC calculada |
Content-Type | application/json |
Cálculo de la firma
La firma se calcula siguiendo estos pasos:
1. Preparar los componentes
Necesitas cuatro elementos para construir el string a firmar:
method = "POST" # Método HTTP en mayúsculas
path = "/api/v1/analyze" # Path del endpoint
timestamp = 1705500000000 # Unix timestamp en milisegundos
body = '{"url":"https://example.com"}' # Body JSON2. Calcular hash del body
Calcula el SHA256 del body JSON:
bodyHash = SHA256(body)
= "a1b2c3d4e5..."3. Crear string a firmar
Concatena los cuatro componentes con puntos:
stringToSign = "POST./api/v1/analyze.1705500000000.a1b2c3d4e5..."
└─────────────────────────────────────────────┘
method + path + timestamp + bodyHashImportante: El método debe estar en mayúsculas y el path debe coincidir exactamente con el endpoint que estás llamando.
4. Calcular firma HMAC
Usa HMAC-SHA256 con el hash SHA256 de tu API Secret:
secretHash = SHA256(apiSecret)
signature = HMAC-SHA256(stringToSign, secretHash)Ventana de tiempo
El timestamp debe estar dentro de 5 minutos del tiempo del servidor. Requests con timestamps fuera de esta ventana serán rechazados con error INVALID_TIMESTAMP.
Ejemplo en Node.js
const crypto = require('crypto');
function createSignature(method, path, apiSecret, body, timestamp) {
// Hash del body
const bodyHash = crypto
.createHash('sha256')
.update(body)
.digest('hex');
// String a firmar: method.path.timestamp.bodyHash
const stringToSign = `${method}.${path}.${timestamp}.${bodyHash}`;
// Hash del secret
const secretHash = crypto
.createHash('sha256')
.update(apiSecret)
.digest('hex');
// Firma HMAC
return crypto
.createHmac('sha256', secretHash)
.update(stringToSign)
.digest('hex');
}
// Uso
const apiKey = 'lc_pk_xxxxxxxxxxxxxxxxxxxx';
const apiSecret = 'your_api_secret_here';
const method = 'POST';
const path = '/api/v1/analyze';
const body = JSON.stringify({ url: 'https://example.com' });
const timestamp = Date.now().toString();
const signature = createSignature(method, path, apiSecret, body, timestamp);Ejemplo en Python
import hashlib
import hmac
import json
import time
def create_signature(method: str, path: str, api_secret: str, body: str, timestamp: str) -> str:
# Hash del body
body_hash = hashlib.sha256(body.encode()).hexdigest()
# String a firmar: method.path.timestamp.bodyHash
string_to_sign = f"{method}.{path}.{timestamp}.{body_hash}"
# Hash del secret
secret_hash = hashlib.sha256(api_secret.encode()).hexdigest()
# Firma HMAC
signature = hmac.new(
secret_hash.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return signature
# Uso
api_key = 'lc_pk_xxxxxxxxxxxxxxxxxxxx'
api_secret = 'your_api_secret_here'
method = 'POST'
path = '/api/v1/analyze'
body = json.dumps({'url': 'https://example.com'})
timestamp = str(int(time.time() * 1000))
signature = create_signature(method, path, api_secret, body, timestamp)Ejemplo en PHP
<?php
function createSignature(string $method, string $path, string $apiSecret, string $body, string $timestamp): string {
// Hash del body
$bodyHash = hash('sha256', $body);
// String a firmar: method.path.timestamp.bodyHash
$stringToSign = "{$method}.{$path}.{$timestamp}.{$bodyHash}";
// Hash del secret
$secretHash = hash('sha256', $apiSecret);
// Firma HMAC
return hash_hmac('sha256', $stringToSign, $secretHash);
}
// Uso
$apiKey = 'lc_pk_xxxxxxxxxxxxxxxxxxxx';
$apiSecret = 'your_api_secret_here';
$method = 'POST';
$path = '/api/v1/analyze';
$body = json_encode(['url' => 'https://example.com']);
$timestamp = (string)(round(microtime(true) * 1000));
$signature = createSignature($method, $path, $apiSecret, $body, $timestamp);Verificación de la firma
El servidor verifica la firma siguiendo el mismo proceso:
- Extrae los headers
X-Api-Key,X-TimestampyX-Signature - Verifica que el timestamp esté dentro de la ventana de 5 minutos
- Busca el cliente por API Key y obtiene el hash del secret
- Calcula la firma esperada con el body recibido
- Compara las firmas de forma timing-safe
Si la firma no coincide, el request es rechazado con error INVALID_SIGNATURE.
Errores comunes
| Error | Causa | Solución |
|---|---|---|
MISSING_API_KEY | Falta header X-Api-Key | Incluye el header |
MISSING_TIMESTAMP | Falta header X-Timestamp | Incluye el timestamp |
MISSING_SIGNATURE | Falta header X-Signature | Incluye la firma |
INVALID_API_KEY | API Key no válida | Verifica tu API Key |
INVALID_TIMESTAMP | Timestamp fuera de ventana | Sincroniza el reloj |
INVALID_SIGNATURE | Firma incorrecta | Revisa el cálculo |
Mejores prácticas
- Nunca expongas el API Secret en código cliente o repositorios públicos
- Usa variables de entorno para almacenar las credenciales
- Sincroniza el reloj del servidor para evitar errores de timestamp
- Regenera las credenciales si sospechas que han sido comprometidas