Zum Inhalt

auth-hash: Sichere Link-Hash-Authentifizierung

Installation

Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:

  • RedHat Enterprise Linux 7, 8, 9 und 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-auth-hash
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-auth-hash

Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:

load_module modules/ngx_http_auth_hash_module.so;

Dieses Dokument beschreibt nginx-module-auth-hash v0.1.0, veröffentlicht am 06. Januar 2026.


Beschreibung:

Das Nginx Secure Link HASH-Modul verbessert die Sicherheit und Funktionalität des Standard-Secure-Link-Moduls. Ein sicheres Token wird unter Verwendung einer sicheren HASH-Konstruktion mit einem beliebigen von OpenSSL unterstützten Hash-Algorithmus erstellt, z. B.: blake2b512, blake2s256, gost, md4, md5, mdc2, rmd160, sha1, sha224, sha256, sha3-224, sha3-256, sha3-384, sha3-512, sha384, sha512, sha512-224, sha512-256, shake128, shake256, sm3.

Verwendung:

Die zu hashende Nachricht wird durch auth_hash_message definiert, der secret_key wird durch auth_hash_secret angegeben, und der Hash-Algorithmus H wird durch auth_hash_algorithm definiert.

Zur Verbesserung der Sicherheit sollte die Zeit oder ein Zeitstempel (abhängig vom Datumsformat, das durch den Formatparameter angegeben wird) an die zu hashende Nachricht angehängt werden.

Es ist möglich, Links mit einer begrenzten Lebensdauer zu erstellen. Dies wird durch die optionalen Parameter range_start oder range_end definiert. Wenn der Ablaufzeitraum nicht angegeben ist, hat ein Link eine unbegrenzte Lebensdauer.

Konfigurationsbeispiel für die Serverseite.

location ^~ /files/ {
    # Aktiviert die Funktion, wenn sie deaktiviert ist, ist $auth_hash immer leer
    auth_hash on;

    # Setzt den Zeitwert, der zur Überprüfung verwendet wird.
    # Sie können den Ablaufzeitraum, das Format des Zeitwerts und die Zeitzone des Zeitwerts festlegen
    auth_hash_check_time $arg_ts range_end=$arg_e format=%s;

    # Setzt den Tokenwert, der zur Überprüfung verwendet wird
    # Verfügbare Formate sind hex (Standard), base64, base64url und bin
    auth_hash_check_token $arg_st format=hex;

    # Geheimschlüssel
    auth_hash_secret "my_secret_key";

    # Nachricht, die verifiziert werden soll
    auth_hash_message "$uri|$arg_ts|$arg_e|$auth_hash_secret";

    # Kryptografische Hash-Funktion, die verwendet werden soll
    auth_hash_algorithm sha256;

    # In einer Produktionsumgebung sollten wir potenziellen Angreifern nicht verraten,
    # warum die Hash-Authentifizierung fehlgeschlagen ist
    # - Wenn der Hash falsch ist, ist $auth_hash eine NULL-Zeichenkette.
    # - Wenn der Hash korrekt ist und der Link nicht abgelaufen ist, ist $auth_hash "1".
    if ($auth_hash != "1") {
        return 403;
    }

    rewrite ^/files/(.*)$ /files/$1 break;
}

Die Anwendungseite sollte eine Standard-Hash-Funktion verwenden, um den Hash zu generieren, der dann hex- oder base64url-kodiert werden muss. Beispiel in Perl unten.

Variable $data enthält sicheres Token, Zeitstempel im ISO 8601-Format und Ablaufzeitraum in Sekunden

perl_set $secure_token '
    sub {
        use Digest::SHA qw(sha256_base64);
        use POSIX qw(strftime);

        my $now = time();
        my $secret = "my_very_secret_key";
        my $expire = 60;
        my $tz = strftime("%z", localtime($now));
        $tz =~ s/(\d{2})(\d{2})/$1:$2/;
        my $timestamp = strftime("%Y-%m-%dT%H:%M:%S", localtime($now)) . $tz;
        my $r = shift;
        my $data = $r->uri;

        # hex
        my $string_to_hash = $data . "|" . $timestamp . "|" . $expire . "|" . $secret;
        my $digest_binary = sha256($string_to_hash);
        my $digest = unpack("H*", $digest_binary);

        # base64url
        # my $digest = sha256_base64($data . "|" . $timestamp . "|" . $expire . "|" . $secret);
        # $digest =~ tr/+/_/;
        # $digest =~ s/=+$//;

        $data = "st=" . $digest . "&ts=" . $timestamp . "&e=" . $expire;
        return $data;
    }
';

Eine ähnliche Funktion in PHP

$secret = 'my_very_secret_key';
$expire = 60;
$algo = 'sha256';
$timestamp = date('c');
$unixtimestamp = time();
$stringtosign = "/files/top_secret.pdf|{$unixtimestamp}|{$expire}|{$secret}";
// hex
$hash = bin2hex(hash($algo, $stringtosign, true));
// base64url
// $hash = base64_encode(hash($algo, $stringtosign, true));
// $hash = strtr($hash, '+/', '-_');
// $hash = str_replace('=', '', $hash);
$host = $_SERVER['HTTP_HOST'];
$loc = "https://{$host}/files/top_secret.pdf?st={$hash}&ts={$unixtimestamp}&e={$expire}";

Verwendung des Unix-Zeitstempels in Node.js

const crypto = require("crypto");
const secret = 'my_very_secret_key';
const expire = 60;
const unixTimestamp = Math.round(Date.now() / 1000.);
const stringToSign = `/files/top_secret.pdf|${unixTimestamp}|${expire}|${secret}`;
// hex
const hash = crypto.createHash('sha256').update(stringToSign).digest('hex')
// base64url
// const hash = crypto.createHash('sha256').update(stringToSign).digest('base64')
//       .replace(/=/g, '')
//       .replace(/\+/g, '-')
//       .replace(/\//g, '_');
const loc = `https://host/files/top_secret.pdf?st=${hash}&ts=${unixTimestamp}&e=${expire}`;

Bash-Version

#!/bin/bash

SECRET="my_super_secret"
TIME_STAMP="$(date -d "today + 0 minutes" +%s)";
EXPIRES="3600"; # Sekunden
URL="/file/my_secret_file.txt"
ST="$URL|$TIME_STAMP|$EXPIRES|$SECRET"
## hex
TOKEN="$(echo -n $ST | openssl dgst -sha256 | awk '{print $1}')"
## Base64url
## TOKEN="$(echo -n $ST | openssl dgst -sha256 -binary | openssl base64 | tr +/ -_ | tr -d =)"

echo "http://127.0.0.1$URL?st=$TOKEN&ts=$TIME_STAMP&e=$EXPIRES"

Eingebettete Variablen

  • $auth_hash - Wenn der Hash korrekt ist und der Link nicht abgelaufen ist, ist $auth_hash "1". Andernfalls ist es null.
  • $auth_hash_secret - Der Wert der auth_hash_secret-Direktive

GitHub

Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-auth-hash.