Hoofdstuk 2

Checksum & authenticatie

Elke BigBlueButton-API-call moet een checksum bevatten die is berekend op basis van het shared secret van de server. Dit mechanisme voorkomt ongeautoriseerde toegang en beschermt API-requests tegen manipulatie.

Hoe het werkt

De BBB-API gebruikt een model met shared secret: zowel de server als de aanroepende applicatie kennen hetzelfde geheim. Het geheim wordt nooit direct verzonden — in plaats daarvan wordt het gebruikt als invoer voor een cryptografische hash die als parameter checksum aan elke request wordt toegevoegd.

Het shared secret mag nooit aan eindgebruikers worden blootgesteld. Het hoort uitsluitend thuis in de server-side configuratie van de integrerende applicatie. Verwerk het nooit in JavaScript, mobiele apps of andere client-side code.

Het Shared Secret ophalen

Het geheim is opgeslagen op de BigBlueButton-server in /etc/bigbluebutton/bbb-web.properties als de eigenschap securitySalt. Je kunt het ophalen door de volgende opdracht op de server uit te voeren:

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

Voorbeelduitvoer:

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

De Checksum berekenen (stap voor stap)

Het volgende voorbeeld laat zien hoe je de checksum berekent voor een create-API-call met SHA-256.

— stel alle parameters samen behalve checksum:

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

Plaats de API-methodenaam ervoor (zonder scheidingsteken):

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

Voeg het shared secret toe (zonder scheidingsteken):

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

Bereken de hash met het gekozen algoritme (SHA-256 in dit voorbeeld):

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

Voeg de checksum toe aan de querystring als parameter checksum:

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

Ondersteunde Hash-algoritmen

BigBlueButton ondersteunt verschillende hash-algoritmen voor de berekening van checksum. De volgende tabel geeft alle beschikbare opties weer:

Algoritme Beschikbaar sinds Lengte van de hash
SHA-1 Alle versies 40 tekens
SHA-256 BBB 2.4 64 tekens
SHA-384 BBB 2.5 96 tekens
SHA-512 BBB 2.5 128 tekens

De ondersteunde algoritmen worden server-side geconfigureerd in /etc/bigbluebutton/bbb-web.properties:

supportedChecksumAlgorithms=sha256,sha384,sha512

Als je een algoritme uit deze lijst verwijdert, wordt het op de server uitgeschakeld. Standaard zijn alle vier de algoritmen ingeschakeld.

SHA-1 wordt als verouderd beschouwd. Gebruik SHA-256 of hoger voor nieuwe implementaties. Laat SHA-1 alleen ingeschakeld als je achterwaartse compatibiliteit met oudere integraties nodig hebt.

POST-requests

Houd bij het doen van POST-requests naar de BigBlueButton-API rekening met de volgende regels:

  • De checksum wordt uitsluitend berekend op basis van de URL-querystring.
  • De POST-body (bijv. presentatie-XML of clientSettingsOverride) wordt niet meegenomen in de berekening van de checksum.
  • Alle parameters die deel moeten uitmaken van de checksum moeten in de querystring worden geplaatst.

Configuratie van breakoutrooms

Als je ondersteuning voor SHA-256 uitschakelt, moet je ook de instelling checkSumAlgorithmForBreakouts in /etc/bigbluebutton/bbb-apps-akka.conf bijwerken om ervoor te zorgen dat breakout rooms correct blijven functioneren.

Beveiligingsbest practices

  • Bewaar het gedeelde geheim alleen aan de serverzijde — nooit in JavaScript, mobiele apps of andere contexten aan de clientzijde.
  • Gebruik altijd HTTPS om de checksum en parameters tijdens de overdracht te beschermen.
  • Als je vermoedt dat het geheim is gecompromitteerd, roteer het dan onmiddellijk met bbb-conf --setsecret <new-secret>.
  • Het checksum-mechanisme beschermt tegen manipulatie, maar niet tegen replay-aanvallen. Overweeg voor join-URL's het gebruik van de parameter createTime om de geldigheid te beperken.

Neem bij het genereren van join-links voor gebruikers de parameter createTime op uit het oorspronkelijke create-antwoord. Dit zorgt ervoor dat de deelnamelink alleen geldig is voor die specifieke vergaderingsinstantie.

Codevoorbeelden

De volgende voorbeelden demonstreren de berekening van checksum met SHA-256 om een vergadering aan te maken.

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

Volledig voorbeeld: een vergadering aanmaken en deelnemen aan (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}"

Veelgestelde vragen

De checksum is een cryptografische hash die aan elk API-verzoek wordt toegevoegd. Deze bewijst dat de aanroeper het gedeelde geheim kent zonder het geheim zelf te verzenden. Zonder een geldige checksum wijst de BigBlueButton-server het verzoek af.

Gebruik SHA-256 of hoger voor alle nieuwe implementaties. SHA-1 wordt ondersteund voor achterwaartse compatibiliteit, maar wordt als verouderd beschouwd. SHA-384 en SHA-512 zijn beschikbaar vanaf BigBlueButton 2.5.

Nee. De checksum wordt uitsluitend berekend op basis van de URL-query string. De POST-body (zoals presentatie-XML of client settings overrides) wordt niet meegenomen in de berekening van de checksum.

Voer het commando bbb-conf --setsecret <new-secret> uit op je BigBlueButton-server. Werk na het wijzigen van het geheim onmiddellijk alle geïntegreerde applicaties bij, aangezien het oude geheim niet langer wordt geaccepteerd.

Ja. Bewerk de eigenschap supportedChecksumAlgorithms in /etc/bigbluebutton/bbb-web.properties en verwijder de algoritmen die je wilt uitschakelen. Als je SHA-256 uitschakelt, werk dan ook de instelling checkSumAlgorithmForBreakouts in bbb-apps-akka.conf bij.

Omdat de checksum het gedeelde geheim bevat als onderdeel van de invoer voor de hash, zal elke wijziging aan de parameters van de query een andere hash opleveren. De server herberekent de checksum aan zijn kant en wijst het verzoek af als de waarden niet overeenkomen.

Nee. Het checksum-mechanisme bevat standaard geen tijdstempel of nonce. Om replay-aanvallen op join-URL's te beperken, neem je de parameter createTime op uit het oorspronkelijke create-antwoord. Dit koppelt de join-link aan een specifieke vergaderingsinstantie.