Глава 2

Kontrolnaya summa i autentifikaciya

Каждый вызов API BigBlueButton должен включать checksum, вычисленный на основе shared secret сервера. Этот механизм предотвращает несанкционированный доступ и защищает API-запросы от подмены.

Как это работает

API BBB использует модель shared-secret: и сервер, и вызывающее приложение знают один и тот же секрет. Сам секрет никогда не передаётся напрямую — вместо этого он используется как вход для криптографического hash, который добавляется к каждому запросу как параметр checksum.

shared secret никогда не должен раскрываться конечным пользователям. Ему место исключительно в серверной конфигурации интегрируемого приложения. Никогда не встраивайте его в JavaScript, мобильные приложения или любой другой клиентский код.

Получение Shared Secret

Секрет хранится на сервере BigBlueButton в /etc/bigbluebutton/bbb-web.properties как свойство securitySalt. Вы можете получить его, выполнив на сервере следующую команду:

# On the BBB server:
sudo bbb-conf --secret

Пример вывода:

URL: https://api-guide.bbbserver.com/bigbluebutton/
Secret: replace-with-secret

Вычисление Checksum (пошагово)

Следующий пример показывает, как вычислить checksum для вызова API create с использованием SHA-256.

— объедините все параметры, кроме checksum:

name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password

Добавьте в начало имя метода API (без какого-либо разделителя):

createname=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password

Добавьте в конец shared secret (без какого-либо разделителя):

createname=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-passwordreplace-with-secret

Вычислите hash с использованием выбранного алгоритма (в этом примере SHA-256):

SHA-1:   7030bd96ede6a7ac41da848fe3bfc562e52a5914
SHA-256: 7e5a0a48f1542462e56ca034dc83d741bff1deb5feab0cd9ef74fa6e009fe1fd

Добавьте checksum к строке запроса как параметр checksum:

name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password&checksum=7e5a0a48f1542462e56ca034dc83d741bff1deb5feab0cd9ef74fa6e009fe1fd

Поддерживаемые алгоритмы Hash

BigBlueButton поддерживает несколько алгоритмов hash для вычисления checksum. В следующей таблице перечислены все доступные варианты:

Алгоритм Доступно с версии Длина Hash
SHA-1 Все версии 40 символов
SHA-256 BBB 2.4 64 символа
SHA-384 BBB 2.5 96 символов
SHA-512 BBB 2.5 128 символов

Поддерживаемые алгоритмы настраиваются на стороне сервера в /etc/bigbluebutton/bbb-web.properties:

supportedChecksumAlgorithms=sha256,sha384,sha512

Удаление алгоритма из этого списка отключает его на сервере. По умолчанию включены все четыре алгоритма.

SHA-1 считается устаревшим. Для новых реализаций используйте SHA-256 или выше. Оставляйте SHA-1 включённым только если вам нужна обратная совместимость со старыми интеграциями.

Запросы POST

При выполнении запросов POST к API BigBlueButton учитывайте следующие правила:

  • checksum вычисляется исключительно из URL-строки запроса.
  • Тело POST (например, XML презентации или clientSettingsOverride) не включается в вычисление checksum.
  • Все параметры, которые должны быть частью checksum, необходимо помещать в строку запроса.

Конфигурация групповых комнат

Если вы отключаете поддержку SHA-256, вы также должны обновить параметр checkSumAlgorithmForBreakouts в /etc/bigbluebutton/bbb-apps-akka.conf, чтобы групповые комнаты продолжали работать корректно.

Лучшие практики безопасности

  • Храните общий секрет только на стороне сервера — никогда не в JavaScript, мобильных приложениях или других клиентских контекстах.
  • Всегда используйте HTTPS для защиты контрольной суммы и параметров во время передачи.
  • Если вы подозреваете, что секрет был скомпрометирован, немедленно замените его с помощью bbb-conf --setsecret <new-secret>.
  • Механизм контрольной суммы защищает от подмены, но не от атак повторного воспроизведения. Для URL join рассмотрите возможность использования параметра createTime для ограничения срока действия.

При создании ссылок join для пользователей включайте параметр createTime из исходного ответа create. Это гарантирует, что ссылка для входа действительна только для этого конкретного экземпляра встречи.

Примеры кода

Следующие примеры демонстрируют вычисление контрольной суммы с использованием SHA-256 для создания встречи.

Python 3

import hashlib
import urllib.parse
import requests

BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET = "replace-with-secret"

def bbb_checksum(call_name: str, query_string: str) -> str:
    """Calculate the BBB API checksum (SHA-256)."""
    raw = call_name + query_string + BBB_SECRET
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

# Create a meeting
params = urllib.parse.urlencode({
    "name": "Demo",
    "meetingID": "replace-with-meeting-id",
    "attendeePW": "replace-with-password",
    "moderatorPW": "replace-with-password",
})
checksum = bbb_checksum("create", params)
response = requests.get(f"{BBB_URL}/create?{params}&checksum={checksum}")
print(response.text)

PHP

<?php
$bbbUrl    = "https://api-guide.bbbserver.com/bigbluebutton/api";
$bbbSecret = "replace-with-secret";

function bbbChecksum(string $callName, string $queryString, string $secret): string {
    return hash("sha256", $callName . $queryString . $secret);
}

// Create a meeting
$params = http_build_query([
    "name"        => "Demo",
    "meetingID"   => "replace-with-meeting-id",
    "attendeePW"  => "replace-with-password",
    "moderatorPW" => "replace-with-password",
]);
$checksum = bbbChecksum("create", $params, $bbbSecret);
$response = file_get_contents("{$bbbUrl}/create?{$params}&checksum={$checksum}");
echo $response;

JavaScript (Node.js)

const crypto = require("crypto");
const https = require("https");

const BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api";
const BBB_SECRET = "replace-with-secret";

function bbbChecksum(callName, queryString) {
  return crypto
    .createHash("sha256")
    .update(callName + queryString + BBB_SECRET)
    .digest("hex");
}

// Create a meeting
const params = new URLSearchParams({
    name: "Demo",
    meetingID: "replace-with-meeting-id",
    attendeePW: "replace-with-password",
    moderatorPW: "replace-with-password",
}).toString();

const checksum = bbbChecksum("create", params);
https.get(`${BBB_URL}/create?${params}&checksum=${checksum}`, (res) => {
  let data = "";
  res.on("data", (chunk) => (data += chunk));
  res.on("end", () => console.log(data));
});

Java

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class BbbApi {
    static final String BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api";
    static final String BBB_SECRET = "replace-with-secret";

    static String bbbChecksum(String callName, String queryString) throws Exception {
        String raw = callName + queryString + BBB_SECRET;
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(raw.getBytes(StandardCharsets.UTF_8));
        StringBuilder hex = new StringBuilder();
        for (byte b : hash) hex.append(String.format("%02x", b));
        return hex.toString();
    }

    public static void main(String[] args) throws Exception {
        String params = "name=" + URLEncoder.encode("Demo", "UTF-8")
            + "&meetingID=replace-with-meeting-id"
            + "&attendeePW=replace-with-password"
            + "&moderatorPW=replace-with-password";
        String checksum = bbbChecksum("create", params);
        String url = BBB_URL + "/create?" + params + "&checksum=" + checksum;
        System.out.println(url);
    }
}

Ruby

require "digest"
require "uri"
require "net/http"

BBB_URL    = "https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET = "replace-with-secret"

def bbb_checksum(call_name, query_string)
  Digest::SHA256.hexdigest(call_name + query_string + BBB_SECRET)
end

# Create a meeting
params = URI.encode_www_form(
    name: "Demo",
    meetingID: "replace-with-meeting-id",
    attendeePW: "replace-with-password",
    moderatorPW: "replace-with-password"
)
checksum = bbb_checksum("create", params)
uri = URI("#{BBB_URL}/create?#{params}&checksum=#{checksum}")
puts Net::HTTP.get(uri)

curl (Bash)

BBB_URL="https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET="replace-with-secret"

CALL="create"
PARAMS="name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password"
CHECKSUM=$(echo -n "${CALL}${PARAMS}${BBB_SECRET}" | sha256sum | awk '{print $1}')

curl -s "${BBB_URL}/${CALL}?${PARAMS}&checksum=${CHECKSUM}"

Полный пример: Создание и присоединение к встрече (curl)

#!/bin/bash
BBB_URL="https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET="replace-with-secret"

bbb_checksum() {
  echo -n "${1}${2}${BBB_SECRET}" | sha256sum | awk '{print $1}'
}

# 1. Create a meeting
CREATE_PARAMS="name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password"
CREATE_CS=$(bbb_checksum "create" "$CREATE_PARAMS")
curl -s "${BBB_URL}/create?${CREATE_PARAMS}&checksum=${CREATE_CS}"

# 2. Generate moderator join URL
JOIN_PARAMS="meetingID=replace-with-meeting-id&fullName=Admin&role=MODERATOR&redirect=true"
JOIN_CS=$(bbb_checksum "join" "$JOIN_PARAMS")
echo ""
echo "Moderator URL: ${BBB_URL}/join?${JOIN_PARAMS}&checksum=${JOIN_CS}"

# 3. Generate viewer join URL
JOIN_PARAMS2="meetingID=replace-with-meeting-id&fullName=Guest&role=VIEWER&redirect=true"
JOIN_CS2=$(bbb_checksum "join" "$JOIN_PARAMS2")
echo "Viewer URL: ${BBB_URL}/join?${JOIN_PARAMS2}&checksum=${JOIN_CS2}"

# 4. Check meeting status
INFO_CS=$(bbb_checksum "getMeetingInfo" "meetingID=replace-with-meeting-id")
curl -s "${BBB_URL}/getMeetingInfo?meetingID=replace-with-meeting-id&checksum=${INFO_CS}"

Часто задаваемые вопросы

Контрольная сумма — это криптографический хеш, добавляемый к каждому API-запросу. Он доказывает, что вызывающая сторона знает общий секрет, не передавая сам секрет. Без действительной контрольной суммы сервер BigBlueButton отклоняет запрос.

Используйте SHA-256 или выше для всех новых реализаций. SHA-1 поддерживается для обратной совместимости, но считается устаревшим. SHA-384 и SHA-512 доступны начиная с BigBlueButton 2.5.

Нет. Контрольная сумма вычисляется исключительно из URL строки запроса. Тело POST (например, XML презентации или переопределения настроек клиента) не включается в вычисление контрольной суммы.

Выполните команду bbb-conf --setsecret <new-secret> на вашем сервере BigBlueButton. После изменения секрета немедленно обновите все интегрированные приложения, так как старый секрет больше не будет приниматься.

Да. Отредактируйте свойство supportedChecksumAlgorithms в /etc/bigbluebutton/bbb-web.properties и удалите алгоритмы, которые хотите отключить. Если вы отключаете SHA-256, также обновите параметр checkSumAlgorithmForBreakouts в bbb-apps-akka.conf.

Поскольку контрольная сумма включает общий секрет как часть входных данных для хеша, любое изменение параметров query приведёт к другому хешу. Сервер пересчитывает контрольную сумму на своей стороне и отклоняет запрос, если значения не совпадают.

Нет. Механизм контрольной суммы по умолчанию не включает метку времени или nonce. Чтобы снизить риск атак повторного воспроизведения для URL join, включайте параметр createTime из исходного ответа create. Это привязывает ссылку join к конкретному экземпляру встречи.
Руководство по API BigBlueButton