Capitolo 2

Checksum e autenticazione

Ogni chiamata API BigBlueButton deve includere un checksum calcolato a partire dal shared secret del server. Questo meccanismo impedisce accessi non autorizzati e protegge le richieste API da manomissioni.

Come funziona

L'API BBB usa un modello a shared-secret: sia il server sia l'applicazione chiamante conoscono lo stesso segreto. Il segreto non viene mai trasmesso direttamente — viene invece usato come input per un hash crittografico che viene aggiunto a ogni richiesta come parametro checksum.

Il shared secret non deve mai essere esposto agli utenti finali. Appartiene esclusivamente alla configurazione lato server dell'applicazione che effettua l'integrazione. Non incorporarlo mai in JavaScript, app mobili o qualsiasi altro codice lato client.

Recupero dello Shared Secret

Il segreto è memorizzato sul server BigBlueButton in /etc/bigbluebutton/bbb-web.properties come proprietà securitySalt. Puoi recuperarlo eseguendo il seguente comando sul server:

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

Output di esempio:

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

Calcolo del Checksum (passo dopo passo)

L'esempio seguente dimostra come calcolare il checksum per una chiamata API create usando SHA-256.

— assembla tutti i parametri tranne checksum:

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

Anteponi il nome del metodo API (senza alcun separatore):

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

Aggiungi in coda il shared secret (senza alcun separatore):

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

Calcola l'hash usando l'algoritmo scelto (SHA-256 in questo esempio):

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

Aggiungi il checksum alla query string come parametro checksum:

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

Algoritmi di Hash supportati

BigBlueButton supporta diversi algoritmi di hash per il calcolo del checksum. La tabella seguente elenca tutte le opzioni disponibili:

Algoritmo Disponibile da Lunghezza dell'Hash
SHA-1 Tutte le versioni 40 caratteri
SHA-256 BBB 2.4 64 caratteri
SHA-384 BBB 2.5 96 caratteri
SHA-512 BBB 2.5 128 caratteri

Gli algoritmi supportati sono configurati lato server in /etc/bigbluebutton/bbb-web.properties:

supportedChecksumAlgorithms=sha256,sha384,sha512

Rimuovere un algoritmo da questo elenco lo disabilita sul server. Per impostazione predefinita, tutti e quattro gli algoritmi sono abilitati.

SHA-1 è considerato deprecato. Usa SHA-256 o superiore per le nuove implementazioni. Mantieni SHA-1 abilitato solo se hai bisogno di compatibilità retroattiva con integrazioni più vecchie.

Richieste POST

Quando effettui richieste POST all'API BigBlueButton, tieni presenti le seguenti regole:

  • Il checksum viene calcolato esclusivamente dalla query string dell'URL.
  • Il corpo POST (ad es. XML della presentazione o clientSettingsOverride) non è incluso nel calcolo del checksum.
  • Tutti i parametri che devono far parte del checksum devono essere inseriti nella query string.

Configurazione delle stanze di sottogruppo

Se disabiliti il supporto SHA-256, devi anche aggiornare l'impostazione checkSumAlgorithmForBreakouts in /etc/bigbluebutton/bbb-apps-akka.conf per garantire che le stanze per sottogruppi continuino a funzionare correttamente.

Migliori pratiche di sicurezza

  • Conserva il segreto condiviso solo sul lato server — mai in JavaScript, nelle app mobili o in altri contesti lato client.
  • Usa sempre HTTPS per proteggere il checksum e i parametri durante la trasmissione.
  • Se sospetti che il segreto sia stato compromesso, ruotalo immediatamente usando bbb-conf --setsecret <new-secret>.
  • Il meccanismo di checksum protegge dalle manomissioni ma non dagli attacchi replay. Per gli URL di join, valuta l'uso del parametro createTime per limitarne la validità.

Quando generi link join per gli utenti, includi il parametro createTime della risposta create originale. Questo garantisce che il link di accesso sia valido solo per quella specifica istanza della riunione.

Esempi di codice

I seguenti esempi dimostrano il calcolo del checksum usando SHA-256 per creare una riunione.

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

Esempio completo: Crea e Partecipa a una riunione (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}"

Domande frequenti

Il checksum è un hash crittografico aggiunto a ogni richiesta API. Dimostra che il chiamante conosce il segreto condiviso senza trasmettere il segreto stesso. Senza un checksum valido, il server BigBlueButton rifiuta la richiesta.

Usa SHA-256 o superiore per tutte le nuove implementazioni. SHA-1 è supportato per compatibilità con le versioni precedenti, ma è considerato deprecato. SHA-384 e SHA-512 sono disponibili a partire da BigBlueButton 2.5.

No. Il checksum viene calcolato esclusivamente dalla query string dell'URL. Il corpo della richiesta POST (come XML della presentazione o sovrascritture delle impostazioni client) non è incluso nel calcolo del checksum.

Esegui il comando bbb-conf --setsecret <new-secret> sul tuo server BigBlueButton. Dopo aver cambiato il segreto, aggiorna immediatamente tutte le applicazioni integrate, poiché il vecchio segreto non sarà più accettato.

Sì. Modifica la proprietà supportedChecksumAlgorithms in /etc/bigbluebutton/bbb-web.properties e rimuovi gli algoritmi che vuoi disabilitare. Se disabiliti SHA-256, aggiorna anche l'impostazione checkSumAlgorithmForBreakouts in bbb-apps-akka.conf.

Poiché il checksum include il segreto condiviso come parte dell'input del hash, qualsiasi modifica ai parametri della query produrrà un hash diverso. Il server ricalcola il checksum dal proprio lato e rifiuta la richiesta se i valori non corrispondono.

No. Il meccanismo di checksum non include per impostazione predefinita un timestamp o un nonce. Per mitigare gli attacchi replay sugli URL di join, includi il parametro createTime dalla risposta originale di create. Questo collega il link join a una specifica istanza della riunione.