Pular para o conteúdo

TLDR: Integração do Servidor ALTCHA

Este guia oferece uma visão geral concisa de como integrar o ALTCHA no seu servidor, cobrindo ambos os modos: com e sem o filtro de spam. Seguindo esses passos, você garantirá uma verificação segura e eficiente das submissões do usuário, seja para uma verificação de desafio básica ou para um filtro avançado de spam.

Para uma integração fácil, considere usar as bibliotecas oficiais:

Visão Geral da Configuração

  1. Recuperar Desafio:

    • O cliente busca um desafio usando o widget ALTCHA.
  2. Resolver Desafio:

    • O cliente resolve o desafio.
  3. Enviar Solução:

    • Solução e dados do usuário são enviados para o servidor.
  4. Verificação no Servidor:

    • O servidor valida a solução e, se estiver usando o filtro de spam, valida a classificação de spam.

Sem Filtro de Spam

Documentação completa: Integração do Servidor

Criando um Desafio (Lado do Servidor)

  • Gerar Parâmetros:
    • maxnumber: Número máximo aleatório (ajusta a dificuldade).
    • salt: String aleatória (≥10 caracteres).
    • secret_number: Inteiro aleatório (0…maxnumber).
    • challenge: Hash SHA-256 de salt + secret_number.
    • signature: HMAC-SHA-256 de challenge com uma chave secreta.
maxnumber = 100_000;
salt = random_string();
secret_number = random_int(maxnumber);
challenge = sha2_hex(concat(salt, secret_number));
signature = hmac_sha2_hex(challenge, hmac_key);
response = {
algorithm: 'SHA-256',
challenge,
maxnumber,
salt,
signature,
};

Validando uma Solução (Lado do Servidor)

  • Decodificar Payload:

    • Extrair algorithm, challenge, number, salt, signature do payload Base64-JSON.
  • Passos de Validação:

    • alg_ok: Verificar se o algoritmo é ‘SHA-256’.
    • challenge_ok: Verificar se o challenge coincide com sha2_hex(concat(salt, number)).
    • signature_ok: Verificar se a signature coincide com hmac_sha2_hex(challenge, hmac_key).
data = json_decode(base64_decode(payload));
alg_ok = equals(data.algorithm, 'SHA-256');
challenge_ok = equals(data.challenge, sha2_hex(concat(data.salt, data.number)));
signature_ok = equals(data.signature, hmac_sha2_hex(data.challenge, hmac_key));
verified = alg_ok && challenge_ok && signature_ok;

Com Filtro de Spam

Documentação completa: Integração do Servidor

Usando a API com o Widget

  • Configuração do Widget:
    • Defina challengeurl com sua chave de API.
    • Ative spamfilter para classificação de spam.
<altcha-widget
challengeurl="https://eu.altcha.org/api/v1/challenge?apiKey=ckey_..."
spamfilter
></altcha-widget>

Verificação no Servidor

  • Formato do Payload:
    • Você recebe um objeto JSON codificado em base64 com as propriedades algorithm, signature, verificationData e verified.
{
"algorithm": "SHA-256",
"signature": "71b86949a1a84595f71d8abd7bdef414e8b883247e30cba93f4946b028c4fbf1",
"verificationData": "classification=BAD&score=7.75&...&time=1713566250&verified=true",
"verified": true
}

Verificando a Assinatura

  1. Calcule o hash SHA de verificationData.
  2. Compute a assinatura HMAC usando a parte secreta da sua chave de API.

Exemplo de pseudo-código:

hash = sha2(payload.verificationData);
signature = hmac_sha2_hex(hash, hmac_key);
  • Verificação:
    • O payload é verificado se a assinatura calculada coincidir com a propriedade signature.

Verificar Campos (Filtro de Spam)

  • Verificar fields e fieldsHash:
    • Concatene os valores dos campos com \n e calcule a hash SHA.

Exemplo de pseudo-código:

hash = sha2_hex(field1_value + "\n" + field2_value + "\n" + field3_value);
  • Validação:
    • Os dados estão corretos se a hash calculada coincidir com fieldsHash.

Código de Exemplo

  • Exemplo em Node.js:
import { createChallenge, verifySolution } from 'altcha-lib';
const hmacKey = '$ecret.key'; // Chave HMAC secreta
// Crie um novo desafio
const challenge = await createChallenge({ hmacKey });
// Verifique o payload enviado
const ok = await verifySolution(payload, hmacKey);

Recomendações de Segurança

  • Prevenir Ataques de Replay:

    • Invalide desafios previamente resolvidos.
  • Expiração do Desafio:

    • Inclua um carimbo de hora no salt para limitar o período de validade.
    • Use salt = '<random_salt>?expires=<unix_ts>'.

Pontos de Extensão da API

  • Criar um Novo Desafio:

    • GET /api/v1/challenge
  • Verificar Solução:

    • POST /api/v1/challenge/verify
  • Validar Assinatura do Servidor:

    • POST /api/v1/challenge/verify_server_signature