Rozdział 2

Suma kontrolna i uwierzytelnianie

Każde wywołanie API BigBlueButton musi zawierać checksum obliczoną na podstawie shared secret serwera. Mechanizm ten zapobiega nieautoryzowanemu dostępowi i chroni żądania API przed manipulacją.

Jak to działa

API BBB używa modelu shared-secret: zarówno serwer, jak i wywołująca aplikacja znają ten sam sekret. Sekret nigdy nie jest przesyłany bezpośrednio — zamiast tego jest używany jako dane wejściowe do kryptograficznego hash, który jest dołączany do każdego żądania jako parametr checksum.

Shared secret nigdy nie może być ujawniony użytkownikom końcowym. Powinien znajdować się wyłącznie w konfiguracji po stronie serwera aplikacji integrującej. Nigdy nie osadzaj go w JavaScript, aplikacjach mobilnych ani żadnym innym kodzie po stronie klienta.

Pobieranie Shared Secret

Sekret jest przechowywany na serwerze BigBlueButton w /etc/bigbluebutton/bbb-web.properties jako właściwość securitySalt. Możesz go pobrać, uruchamiając na serwerze następujące polecenie:

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

Przykładowy wynik:

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

Obliczanie Checksum (krok po kroku)

Poniższy przykład pokazuje, jak obliczyć checksum dla wywołania API create przy użyciu SHA-256.

— zestaw wszystkie parametry z wyjątkiem checksum:

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

Poprzedź go nazwą metody API (bez żadnego separatora):

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

Dołącz shared secret (bez żadnego separatora):

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

Oblicz hash przy użyciu wybranego algorytmu (w tym przykładzie SHA-256):

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

Dołącz checksum do ciągu zapytania jako parametr checksum:

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

Obsługiwane algorytmy Hash

BigBlueButton obsługuje kilka algorytmów hash do obliczania checksum. Poniższa tabela zawiera wszystkie dostępne opcje:

Algorytm Dostępne od Długość Hash
SHA-1 Wszystkie wersje 40 znaków
SHA-256 BBB 2.4 64 znaki
SHA-384 BBB 2.5 96 znaków
SHA-512 BBB 2.5 128 znaków

Obsługiwane algorytmy są konfigurowane po stronie serwera w /etc/bigbluebutton/bbb-web.properties:

supportedChecksumAlgorithms=sha256,sha384,sha512

Usunięcie algorytmu z tej listy powoduje jego wyłączenie na serwerze. Domyślnie wszystkie cztery algorytmy są włączone.

SHA-1 jest uznawany za przestarzały. W nowych implementacjach używaj SHA-256 lub wyższych. Pozostaw SHA-1 włączone tylko wtedy, gdy potrzebujesz zgodności wstecznej ze starszymi integracjami.

Żądania POST

Wysyłając żądania POST do API BigBlueButton, pamiętaj o następujących zasadach:

  • checksum jest obliczana wyłącznie na podstawie ciągu query string URL-a.
  • Treść POST (np. XML prezentacji lub clientSettingsOverride) nie jest uwzględniana przy obliczaniu checksum.
  • Wszystkie parametry, które mają być częścią checksum, muszą zostać umieszczone w query string.

Konfiguracja pokoi grupowych

Jeśli wyłączysz obsługę SHA-256, musisz również zaktualizować ustawienie checkSumAlgorithmForBreakouts w /etc/bigbluebutton/bbb-apps-akka.conf, aby pokoje podgrup nadal działały poprawnie.

Najlepsze praktyki bezpieczeństwa

  • Przechowuj wspólny sekret wyłącznie po stronie serwera — nigdy w JavaScripcie, aplikacjach mobilnych ani w innych kontekstach po stronie klienta.
  • Zawsze używaj HTTPS, aby chronić sumę kontrolną i parametry podczas transmisji.
  • Jeśli podejrzewasz, że sekret został ujawniony, natychmiast go zmień za pomocą bbb-conf --setsecret <new-secret>.
  • Mechanizm sumy kontrolnej chroni przed manipulacją, ale nie przed atakami powtórzeniowymi. W przypadku adresów URL join rozważ użycie parametru createTime do ograniczenia okresu ważności.

Podczas generowania linków join dla użytkowników uwzględnij parametr createTime z oryginalnej odpowiedzi create. Dzięki temu link dołączenia będzie ważny tylko dla tej konkretnej instancji spotkania.

Przykłady kodu

Poniższe przykłady pokazują obliczanie sumy kontrolnej przy użyciu SHA-256 w celu utworzenia spotkania.

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}"

Pełny przykład: Utworzenie i dołączenie do spotkania (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}"

Najczęściej zadawane pytania

Suma kontrolna to kryptograficzny hasz dołączany do każdego żądania API. Dowodzi, że wywołujący zna wspólny sekret, nie przesyłając samego sekretu. Bez prawidłowej sumy kontrolnej serwer BigBlueButton odrzuci żądanie.

Używaj SHA-256 lub wyższego dla wszystkich nowych implementacji. SHA-1 jest obsługiwany ze względu na zgodność wsteczną, ale jest uznawany za przestarzały. SHA-384 i SHA-512 są dostępne od BigBlueButton 2.5.

Nie. Suma kontrolna jest obliczana wyłącznie na podstawie URL query string. Treść POST (np. XML prezentacji lub nadpisania ustawień klienta) nie jest uwzględniana przy obliczaniu sumy kontrolnej.

Uruchom polecenie bbb-conf --setsecret <new-secret> na swoim serwerze BigBlueButton. Po zmianie sekretu natychmiast zaktualizuj wszystkie zintegrowane aplikacje, ponieważ stary sekret nie będzie już akceptowany.

Tak. Edytuj właściwość supportedChecksumAlgorithms w /etc/bigbluebutton/bbb-web.properties i usuń algorytmy, które chcesz wyłączyć. Jeśli wyłączysz SHA-256, zaktualizuj również ustawienie checkSumAlgorithmForBreakouts w bbb-apps-akka.conf.

Ponieważ suma kontrolna zawiera wspólny sekret jako część danych wejściowych haszu, każda modyfikacja parametrów query spowoduje wygenerowanie innego haszu. Serwer ponownie oblicza sumę kontrolną po swojej stronie i odrzuca żądanie, jeśli wartości się nie zgadzają.

Nie. Mechanizm sumy kontrolnej domyślnie nie zawiera znacznika czasu ani nonce. Aby ograniczyć ataki powtórzeniowe dla adresów URL join, dołącz parametr createTime z oryginalnej odpowiedzi create. Powiązuje to link join z konkretną instancją spotkania.