Betrieb schickt ein Datenbankpasswort, einen API-Schlüssel oder einen Recovery-Code an Kolleginnen. Der schnellste Weg: in den Chat kleben. Die Nachricht ist durchsuchbar, synchronisiert sich auf mehrere Geräte und taucht ein halbes Jahr später noch in der Suche auf. Wer stattdessen einen «Einmal-Link» baut, hängt den Entschlüsselungsschlüssel oft als ?key= hinter die ID. Dann sehen Host, Reverse-Proxy und Access-Log den Schlüssel — die Verschlüsselung ist halb fertig.
Dieser Text erklärt nicht, welche Schaltfläche du klickst. Das macht die Tool-Seite. Die Frage ist enger: Wenn du ein Passwort einmal schickst, warum der Schlüssel hinter # in der URL gehört, was der Server deshalb nicht sieht, und wo dieser Schutz aufhört. Der vorige Text hat gezeigt, wie du im Network prüfst, dass kein Klartext hochgeladen wird. Dieselbe Methode gilt hier für «in welchem URL-Stück wohnt der Schlüssel». Der Einmal-Link von MyPassGen arbeitet an dieser Grenze: AES-256-GCM im Browser, der Server hält nur Geheimtext, der Schlüssel sitzt hinter #, Erstellen und Lesen ohne Konto.
Zwei Stücke der Adresse trennen
Hinter dem Fragezeichen ? steht der Query-String. Er wandert in die HTTP-Request-Zeile und ins Access-Log der Gegenseite. Hinter der Raute # steht der Fragmentbezeichner. Das Protokoll überlässt ihn dem Client; standardmäßig geht er nicht mit der Anfrage an den Server. Landet der Schlüssel im falschen Stück, hält kein «Zero Knowledge» stand.
Drei Wege, dasselbe Passwort zu schicken
Denselben Testsatz orange-lake-7 kannst du mindestens auf drei Arten weitergeben. Der Unterschied liegt nicht im Werbesatz auf der Seite, sondern darin: Wird der Klartext zuerst zu Geheimtext, wandert der Schlüssel in HTTP, und findest du den Originalsatz in einem halben Jahr noch in der Chat-Suche.
| Vorgehen | Was Host oder Chat bekommen | Was du in einem halben Jahr noch findest |
|---|---|---|
| Passwort direkt in den Chat kleben | Vollständiger Klartext | Durchsuchbares Original |
Verschlüsselter Link, Schlüssel als ?key= |
Geheimtext plus Schlüssel (beide in der Anfrage) | Schlüssel im Access-Log; volle URL im Chat |
Verschlüsselter Link, Schlüssel hinter # |
Server sieht nur die Geheimtext-ID; der Chat kann die volle URL trotzdem speichern | Kein Schlüssel im Server-Log; im Chat kann der volle Link stehen |
Die dritte Variante beantwortet nur: Die Maschine, die den Geheimtext hält, soll den Schlüssel nicht bekommen. Sie beantwortet nicht, ob der Messenger die ganze Adresse speichert. Der volle Link ist ein Beleg: Wer die Adresse mit # kopiert, kann auf der Leseseite entschlüsseln. Die Raute löst Serververtrauen, nicht Weiterleiten.
Kurzer Text gehört auf diesen Weg. MyPassGen begrenzt den Klartext auf 32 KB — Passwort, Schlüsselstück, kurze Anweisung. Zertifikatspaket, Exporttabelle oder alles darüber gehört in die Datei-Verschlüsselung: lokal eine .lock / .enc erzeugen, die Passphrase getrennt schicken, nicht in einen Einmal-Link pressen. Den Dateifall behandelt wer den Klartext sieht, bevor die Datei in die Cloud kommt.
Was HTTP wirklich überträgt
RFC 3986 §3.5 nennt den Teil nach # Fragment Identifier: Er bezeichnet eine sekundäre Stelle, die der Client erst nach dem Abruf der Haupressource auswertet. Der Browser holt die Seite über Pfad und Query; erst wenn die Ressource da ist, entscheidet das Fragment über Scrollposition oder Skript. Die HTTP-Anfrage selbst braucht diesen Abschnitt nicht. Die deutsche Wikipedia sagt dasselbe unter Fragmentbezeichner: Im Gegensatz zum Query-String wird er bei Client-Server-Systemen nicht an den Server übermittelt.
Die geltende HTTP-Semantik ist härter. RFC 9110 §7.1 schreibt: Die Ziel-URI schließt die Fragmentkomponente der Referenz aus, weil das Fragment dem Client vorbehalten bleibt. Eine gültige origin-form in der Request-Zeile ist Pfad plus optionale Query — ohne #. Steht in der Adresszeile s.html?id=abc#schlüssel, muss der Dokumentrequest GET /de/s.html?id=abc sein. Das Stück danach bleibt auf diesem Gerät.
Auch der Referer streicht das Fragment. MDN Referer erlaubt Herkunft, Pfad und Query, nicht URL-Fragment und nicht Benutzername/Passwort. Die W3C-Referrer Policy setzt das Fragment vor dem Senden auf leer. «Der Schlüssel hinter # geht nicht per HTTP an den Host» ist also Protokollverhalten, keine Markenaussage einer einzelnen Seite.
Fragezeichen und Raute sind nicht tauschbar
Nach dem WHATWG-URL-Standard wandert beim Öffnen von http / https alles hinter ? in die Request-Zeile. Schreibst du s.html?id=abc&key=schlüssel, steht der Schlüssel in Access-Log, Reverse-Proxy und oft in CDN-Aufzeichnungen. Welche Query-Namen du bei Marketing-Links löschen darfst, steht in welche Parameter du beim Teilen entfernen darfst — das ist ein anderes Problem. Den Schlüssel darfst du nicht in die Query schieben.
Ein Kodierfehler kommt dazu: %23 ist die Prozentkodierung von #. Steht %23 im Pfad oder in der Query, geht es an den Server und wird nach dem Decodieren zu einem wörtlichen Rautenzeichen — es ist kein Fragment. Der Schlüssel braucht das unkodierte # in der Adresszeile als Trenner, nicht ein %23, das im Pfad steckt.
Was im Server-Log fehlt
Ein vollständiger Einmal-Link hat zwei Schritte. Beim Anlegen erzeugt der Browser einen 32-Byte-Zufallsschlüssel, verschlüsselt den Klartext mit AES-256-GCM (12-Byte-IV, zusammen mit dem Geheimtext) und POSTet danach Geheimtext, Gültigkeit und Leseanzahl. Beim Lesen holt das Skript den Schlüssel aus location.hash, fordert nur den Geheimtext an und entschlüsselt auf diesem Gerät. Die Linkform ist s.html?id={id}#{key}: In der Query steht nur die ID, der Schlüssel nur hinter der Raute.
NIST SP 800-38D definiert GCM als authentisierte Verschlüsselung: Wurde der Geheimtext verändert, muss die Entschlüsselung scheitern — nicht ein Kauderwelsch liefern, das du als Text akzeptierst. RFC 5116 beschreibt AEAD_AES_256_GCM mit 32-Byte-Schlüssel, 12-Byte-Nonce und 16-Byte-Auth-Tag. MDN zu AesGcmParams empfiehlt ebenfalls 96 Bit IV; unter demselben Schlüssel muss jede Verschlüsselung einen neuen IV nehmen. Diese Zahlen kannst du in der Implementierung gegenprüfen.
Im Server-Log darfst du also sehen: die Geheimtext-ID id, beim Anlegen die JSON-Felder ciphertext / ttl_hours / max_reads, beim Lesen den GET auf die Geheimtext-Schnittstelle. Im Log darfst du nicht sehen: Klartext, den 32-Byte-Schlüssel oder das Stück hinter # in der Adresszeile. Die Gültigkeit kannst du auf 1 Stunde, 24 Stunden oder 7 Tage setzen, oder nur nach dem Lesen vernichten; die Leseanzahl liegt zwischen 1 und 10. Das steht auf der Erstellseite — kein nachträglich erfundenes SLA.
Das Protokoll regelt nicht, was das Seitenskript selbst sendet
HTTP schickt das Fragment nicht — das heißt nicht, der Schlüssel verlässt dieses Gerät nie. Ein Seitenskript kann window.location.hash lesen und selbst fetchen. Meldet die Analyse die volle location.href als Seitenadresse, wandert das Stück hinter der Raute ins Statistik-Log. Schau im Network auf die Analyse-Requests. Verlass dich nicht auf «HTTP nimmt das sowieso nicht mit».
Der volle Link bleibt ein Beleg
Der Schlüssel hinter # hält den Schlüssel vom HTTP-Dienst, der den Geheimtext hält, fern. Messenger, Mailclient, Browserverlauf und synchronisierte Tabs speichern die Adresse, die der Mensch sieht — inklusive des Stücks hinter der Raute. Wer den vollen Link hat, öffnet die Leseseite und entschlüsselt. Das heißt Bearer-URL: Der Link selbst ist der Beleg. Es gibt kein zweites «nur der Empfänger kennt das Passwort».
Bei empfindlicher Übergabe kannst du teilen: Eine Nachricht nur s.html?id=…, ein zweiter Kanal — Telefon, persönlich oder ein anderer Messenger — nur das Stück hinter #. Ohne beide Hälften geht die Entschlüsselung nicht. Das ist eine Nutzungsart, keine Standardspaltung des Produkts. Standard bleibt ein voller Link, den die Gegenseite einmal öffnet.
Es stoppt auch keinen Screenshot, kein Kopieren und kein Weiterleiten des Klartexts. Einmal-Lesen senkt «der Link wird immer wieder geöffnet» und «der Server hält Klartext dauerhaft». Macht die Gegenseite sofort ein Foto oder klebt den Klartext in eine andere Gruppe, hilft das Protokoll nicht. Geeignet ist nur, was du der Person zutraust und was du ungültig machen und neu schicken kannst. Langzeit-Masterpasswort, privaten Schlüssel oder eine Seed-Phrase schickst du auf diesem Weg nicht.
Im Network nachprüfen
Die Schritte unten hängen an keinem Markenversprechen. Nimm einen wegwerfbaren Testsatz. Übe nicht mit einem echten Datenbankpasswort.
- Öffne die Entwicklertools, Network, und aktiviere «Protokoll beibehalten». Öffne die Erstellseite für den Einmal-Link, schreibe den Testsatz
orange-lake-7, setze die Leseanzahl auf 1 und erzeuge den Link. - Lies den Create-POST: Der Body soll ein Geheimtext-Feld haben, nicht
orange-lake-7. Merke dir den vollen Link. Die Form musss.html?id=…#…sein: hinter der Raute ein Stück, hinter dem Fragezeichen nurid. - Öffne den vollen Link in einem neuen Tab. Die Request-Zeile des Dokumentrequests soll
…/s.html?id=…sein — ohne#und ohne den Schlüssel dahinter. - Prüfe die folgenden Fetch- / XHR-Requests: Der Pfad zum Geheimtext trägt die ID, nicht den Schlüssel. Analyse-Pings dürfen weder das Stück hinter
#noch den Testsatz mitnehmen. - Die Seite soll den Testsatz entschlüsseln. Öffne einen weiteren Tab und füge nur den Teil vor der Raute ein: Die Seite soll «Link unvollständig» sagen, nicht den Originalsatz zeigen.
- Lade den schon gelesenen Link erneut: verbrannt oder abgelaufen, nicht das Original. Neu schicken heißt neu anlegen. Es gibt keine Klartextkopie auf dem Server.
Der Einmal-Link von MyPassGen arbeitet an dieser Grenze: AES-256-GCM, Klartext höchstens 32 KB, Schlüssel hinter #, Erstellen und Lesen ohne Registrierung. Glaub dem Network und «ohne Raute keine Entschlüsselung», nicht dem Wort «Zero Knowledge» auf der Seite. Die festen Grenzen stehen in der Sicherheitserklärung.
Was # nicht schützt
Firmenmail und manche Messenger bauen eine Linkvorschau: Im Hintergrund kommt ein GET, Titel oder Teaser werden gelesen. Eine Vorschau, die nur HTML holt und kein Seitenskript ausführt, bekommt das Fragment nicht und erreicht in der Regel auch die Geheimtext-Schnittstelle nicht. Ein Scanner, der Seitenskripte ausführt, kann vor der empfangenden Person einmal lesen — der Geheimtext ist dann weg. Das ist kein Protokollfehler, sondern die Folge von «Leseseite öffnen heißt: Skript holt Geheimtext». Sagt die Gegenseite, der Link gehe nicht, frage zuerst, ob die Vorschau früher war. Neu schicken heißt neu anlegen.
Browserverlauf, Absturzberichte und manche Sync-Konten merken sich die volle URL. Lässt du den Einmal-Link in der Adresszeile stehen, lässt du den Schlüssel in der lokalen History. Nach dem Lesen gehört die Adresse mit # nicht in eine Ticketvorlage und nicht ins Lesezeichen als «dauerhaftes Backup». Ein verlorener Link ist weg: Es gibt keinen Support, der zurücksetzt, und im Footer steht keine Mailadresse zum Wiederherstellen.
Beim Weiterleiten von Erklärtext sind Link und Fließtext zwei Arbeitsschritte. URLs mit utm_source säuberst du nach der Parameterliste; Telefon- und Ausweisnummern im Ticket maskierst du wie in welche Felder du vor dem Weiterleiten maskieren musst. Der Einmal-Link beantwortet «Host sieht weder Schlüssel noch Klartext», nicht «im Gespräch fehlen vollständige Nummern».
Typische Irrtümer
«Der Schlüssel steht in der URL, also sieht ihn der Server.» Das hängt vom Stück ab. Hinter ?: ja. Hinter #: nach RFC 9110 tragen weder Dokumentrequest noch Referer ihn. Lies die Request-Zeile im Network, nicht das Bauchgefühl.
«Hinter # ist der Chatverlauf sicher.» Der Messenger speichert die Zeichenkette, die jemand kopiert hat. Weniger Schlüssel im Server-Log heißt nicht weniger Schlüssel bei Gruppenmitgliedern oder auf dem Handy, das später in andere Hände kommt.
«Einmal-Lesen verhindert Screenshots.» Nein. Es senkt wiederholtes Öffnen und Klartext auf dem Server, nicht Kopieren und Fotografieren. Nur einmalige Passwörter, die du ungültig machen kannst.
«Die Gegenseite muss sich registrieren, um zu lesen.» Auf dieser Seite brauchen Erstellen und Lesen kein Konto. Die Leseseite ist für die empfangende Person offen. «Öffnen und nutzen» heißt nicht «wer den Link hat, muss sich zuerst anmelden».
Wo du anfängst
Nimm das Passwort, das heute raus muss. Lauf mit einem wegwerfbaren Testsatz die sechs Schritte oben: Create-Request ohne Originalsatz, Request-Zeile der Leseseite ohne das Stück hinter #, ohne Raute keine Entschlüsselung, nach dem Lesen verbrannt. Dann den echten Inhalt.
Das echte Passwort erzeugst du im Passwortgenerator auf diesem Gerät, Zufallsmodus 6–128 Zeichen, Standard 16; unter 8 Zeichen gilt das Ergebnis als schwach. Schick den vollen Link; bei höherer Empfindlichkeit Raute vorne und hinten auf zwei Kanäle. Klebe dasselbe Passwort nicht noch einmal «zur Sicherheit» in den Chat. Danach kannst du die Frage dieses Texts beantworten: Der Schlüssel gehört hinter #, damit der HTTP-Dienst mit dem Geheimtext den Schlüssel nicht sieht. Chatverlauf und Screenshot schützt das nicht.
Häufige Fragen
Sieht der Server den Schlüssel hinter # wirklich nicht?
Nach RFC 9110 enthält die Ziel-URI des Dokumentrequests kein Fragment; der Referer trägt es laut MDN ebenfalls nicht. Öffne Network: In der Request-Zeile der Leseseite darf der Schlüssel hinter der Raute nicht stehen. Meldet das Seitenskript selbst location.href, ist das ein Implementierungsfehler — den siehst du in der Fetch-Liste.
Muss sich die Gegenseite registrieren, um den Link zu öffnen?
Nein. Erstellen und Lesen brauchen kein Konto. Die empfangende Person öffnet die Leseseite und entschlüsselt. Nach der eingestellten Anzahl ist der Inhalt weg, oder die TTL ist abgelaufen. Ein weiteres Öffnen zeigt verbrannt oder abgelaufen, nicht das Original.
Ich habe nur den Teil vor der Raute kopiert. Geht der Link noch?
Ohne den Schlüssel hinter # gibt es keine Entschlüsselung. Die Leseseite soll «Link unvollständig» sagen. Hol den vollen Link bei der sendenden Person. Verlorener oder verbrannter Link ist nicht wiederherstellbar. Neu schicken heißt neu anlegen.
Verhindert das, dass der Messenger eine Spur hinterlässt?
Nein. Messenger speichern in der Regel die volle Adresse, die du einfügst — inklusive Schlüssel. Die Raute hält den Schlüssel nur vom HTTP-Dienst mit dem Geheimtext fern. Soll der Gruppenverlauf keinen Beleg halten, schick den vollen Link nicht in einen Kanal, der lange bleibt.