Proof-Of-Work captcha
  • JavaScript 79.8%
  • HTML 20.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-11 13:19:15 +03:00
client Initial commit: VivaRAT Captcha standalone module 2026-09-11 13:15:45 +03:00
example Remove emojis from documentation, example and server 2026-09-11 13:16:47 +03:00
server Initial commit: VivaRAT Captcha standalone module 2026-09-11 13:15:45 +03:00
LLMS.md Add LLMS.md integration guide for AI agents 2026-09-11 13:19:15 +03:00
package.json Initial commit: VivaRAT Captcha standalone module 2026-09-11 13:15:45 +03:00
README.md Remove emojis from documentation, example and server 2026-09-11 13:16:47 +03:00
test.js Initial commit: VivaRAT Captcha standalone module 2026-09-11 13:15:45 +03:00

VivaRAT Captcha

Легковесная, приватная и быстрая Proof-of-Work (PoW) капча для любых веб-сайтов.
Полная независимость от Google reCAPTCHA, Cloudflare Turnstile и hCaptcha. Без слежки, без сторонних серверов, с защитой от ботов и брутфорса.


Преимущества VivaRAT Captcha

  • Никаких сторонних сервисов: Задачи генерируются и проверяются исключительно на вашем собственном сервере.
  • Пользователь не решает светофоры и автобусы: Человек просто нажимает одну кнопку (чекбокс), а браузер решает криптографическую микрозадачу за 100300 миллисекунд.
  • Защита от ботов и спама: Бот не может отправить форму без затрат процессорного времени на поиск валидного хэша.
  • Встроенная криптографическая защита:
    • HMAC-SHA256 подпись каждого челленджа сервером (невозможно подделать).
    • Защита от повторного использования токенов (Replay Attack Prevention).
    • Тайм-аут жизни задачи (по умолчанию 3 минуты).
  • Стильный интерфейс: Плавная анимация спиннера и галочки, поддержка тёмной и светлой тем, авто-адаптация.
  • Работает везде: Чистый HTML/JS, React, Vue, Svelte, Node.js, Python, PHP.

Структура модуля

vivarat-captcha/
├── client/
│   └── vivarat-captcha.js     # Универсальный клиентский JS-виджет (без зависимостей)
├── server/
│   └── vivarat-captcha.js     # Серверная библиотека для Node.js (без зависимостей)
├── example/
│   ├── index.html             # Пример формы авторизации с переключателем тем
│   └── server.js              # Готовый демо-сервер на чистом Node.js
├── test.js                    # Автоматизированные тесты криптографии
└── README.md                  # Документация

Быстрый старт за 2 минуты

1. Быстрый запуск готового примера

В папке уже есть готовый демонстрационный сервер:

cd vivarat-captcha
node example/server.js

Откройте в браузере: http://localhost:3344


Интеграция на клиент (Фронтенд)

Вариант 1: Обычный HTML / Любой сайт

  1. Подключите скрипт vivarat-captcha.js и добавьте контейнер для виджета:
<!-- Контейнер для виджета капчи -->
<div id="captcha-box"></div>

<!-- Подключение скрипта (или скопируйте vivarat-captcha.js к себе в проект) -->
<script src="/path/to/vivarat-captcha.js"></script>

<script>
  // Инициализация
  const captcha = new VivaratCaptcha('#captcha-box', {
    endpoint: '/api/captcha-challenge', // URL вашего эндпоинта выдачи задач
    theme: 'dark',                      // 'dark' или 'light'
    lang: 'ru',                         // 'ru' или 'en'
    onVerified: (token) => {
      console.log('Капча успешно решена, токен:', token);
    }
  });

  // Получить токен при отправке формы через JS:
  // const token = captcha.getToken();
</script>

Примечание: Если виджет находится внутри тега <form>, он автоматически вставляет скрытое поле <input type="hidden" name="vivarat-captcha-token" value="...">, поэтому при обычной отправке формы токен сразу уйдёт на сервер в req.body['vivarat-captcha-token'].


Вариант 2: React / Next.js

import { useEffect, useRef, useState } from 'react';
// Подключите скрипт через <Script> или скопируйте класс

export function CaptchaWidget({ onVerified }) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (window.VivaratCaptcha && containerRef.current) {
      new window.VivaratCaptcha(containerRef.current, {
        endpoint: '/api/captcha-challenge',
        theme: 'dark',
        onVerified: (token) => onVerified(token)
      });
    }
  }, []);

  return <div ref={containerRef}></div>;
}

Интеграция на сервер (Бэкенд)

Node.js / Express

const express = require('express');
const VivaratCaptchaServer = require('./server/vivarat-captcha');

const app = express();
app.use(express.json());

// 1. Инициализация сервера капчи с вашим секретным ключом
const captcha = new VivaratCaptchaServer({
  secret: 'ваш-секретный-ключ-для-продакшна',
  defaultDifficulty: 8000, // Сложность (8000 итераций ~0.15 сек)
  expiresInMs: 3 * 60 * 1000 // 3 минуты
});

// 2. Эндпоинт выдачи задачи клиенту
app.get('/api/captcha-challenge', (req, res) => {
  const challenge = captcha.generateChallenge();
  res.json(challenge);
});

// 3. Проверка капчи при отправке формы
app.post('/api/login', (req, res) => {
  const token = req.body['vivarat-captcha-token'];

  // Проверяем токен капчи
  const verifyResult = captcha.verify(token);

  if (!verifyResult.success) {
    return res.status(400).json({
      error: 'Капча не пройдена',
      reason: verifyResult.error
    });
  }

  // Капча верна! Продолжаем вход / регистрацию
  res.json({ success: true });
});

// Либо используйте встроенный middleware для маршрутов:
// app.post('/api/register', captcha.middleware(), registerHandler);

app.listen(3000);

Другие языки бэкенда (Python / PHP / Go)

Поскольку алгоритм основан на стандартном Proof-of-Work и HMAC-SHA256, его можно проверить на любом языке:

Пример на Python (FastAPI / Flask):

import hmac, hashlib, json, base64, time

SECRET = b'ваш-секретный-ключ'

def verify_captcha(token_b64):
    try:
        data = json.loads(base64.b64decode(token_b64).decode())
        salt, ts, number = data['salt'], data['timestamp'], data['number']
        challenge, sig = data['challenge'], data['signature']

        # 1. Проверка времени (3 мин)
        if time.time() * 1000 - ts > 180000:
            return False

        # 2. Проверка HMAC подписи сервера
        expected_sig = hmac.new(SECRET, f"{challenge}:{ts}".encode(), hashlib.sha256).hexdigest()
        if sig != expected_sig:
            return False

        # 3. Проверка вычисления SHA-256
        computed = hashlib.sha256(f"{salt}:{ts}:{number}".encode()).hexdigest()
        return computed == challenge
    except Exception:
        return False

Пример на PHP:

function verify_captcha($token_b64, $secret) {
    $data = json_decode(base64_decode($token_b64), true);
    if (!$data) return false;

    // Проверка тайм-аута (3 минуты)
    if ((round(microtime(true) * 1000) - $data['timestamp']) > 180000) return false;

    // Проверка подписи
    $expected_sig = hash_hmac('sha256', $data['challenge'] . ':' . $data['timestamp'], $secret);
    if ($data['signature'] !== $expected_sig) return false;

    // Проверка решения PoW
    $computed = hash('sha256', $data['salt'] . ':' . $data['timestamp'] . ':' . $data['number']);
    return $computed === $data['challenge'];
}

Опции клиента (VivaratCaptcha)

Параметр Тип По умолчанию Описание
endpoint string '/api/captcha-challenge' URL адрес сервера, где вызывается generateChallenge()
theme string 'dark' Тема оформления: 'dark' или 'light'
lang string 'ru' Язык текста: 'ru' или 'en'
inputName string 'vivarat-captcha-token' Имя скрытого <input>, создаваемого внутри формы
autoSolve boolean false Автоматически запускать решение при загрузке страницы
onVerified function null Callback-функция (token) => {}, вызываемая при успешном решении
onError function null Callback-функция (err) => {} при возникновении сетевой ошибки

Методы объекта капчи:

  • captcha.getToken() — возвращает текущий base64-токен решения (или пустую строку, если ещё не решено).
  • captcha.reset() — сбрасывает капчу в исходное состояние (нужно после неуспешного входа или для повторной отправки).
  • captcha.solve() — программно запускает процесс решения.

Лицензия

MIT License. Свободно для использования в любых коммерческих и личных проектах. Разработано для сообщества VivaRAT.