Legal Cookies
API

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

CredencialFormatoDescripción
API Keylc_pk_...Identificador público de tu cuenta
API SecretString de 48 caracteresClave 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:

HeaderDescripción
X-Api-KeyTu API Key
X-TimestampUnix timestamp en milisegundos
X-SignatureFirma HMAC calculada
Content-Typeapplication/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 JSON

2. 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 + bodyHash

Importante: 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:

  1. Extrae los headers X-Api-Key, X-Timestamp y X-Signature
  2. Verifica que el timestamp esté dentro de la ventana de 5 minutos
  3. Busca el cliente por API Key y obtiene el hash del secret
  4. Calcula la firma esperada con el body recibido
  5. Compara las firmas de forma timing-safe

Si la firma no coincide, el request es rechazado con error INVALID_SIGNATURE.

Errores comunes

ErrorCausaSolución
MISSING_API_KEYFalta header X-Api-KeyIncluye el header
MISSING_TIMESTAMPFalta header X-TimestampIncluye el timestamp
MISSING_SIGNATUREFalta header X-SignatureIncluye la firma
INVALID_API_KEYAPI Key no válidaVerifica tu API Key
INVALID_TIMESTAMPTimestamp fuera de ventanaSincroniza el reloj
INVALID_SIGNATUREFirma incorrectaRevisa el cálculo

Mejores prácticas

  1. Nunca expongas el API Secret en código cliente o repositorios públicos
  2. Usa variables de entorno para almacenar las credenciales
  3. Sincroniza el reloj del servidor para evitar errores de timestamp
  4. Regenera las credenciales si sospechas que han sido comprometidas