Welche Codierung sollte ich für die HTTP-Basisauthentifizierung verwenden?

84

Der RFC2617 sagt, dass der Benutzername und das Passwort in base64 codiert werden sollen, aber nicht, welche Zeichenkodierung beim Erstellen der Oktette für die Eingabe in den base64-Algorithmus verwendet werden soll.

Sollte ich US-ASCII oder UTF8 annehmen? Oder hat jemand diese Frage schon irgendwo geklärt?

Dobes Vandermeer
quelle

Antworten:

71

Originalspezifikation - RFC 2617

RFC 2617 kann als "ISO-8859-1" oder "undefiniert" gelesen werden. Deine Entscheidung. Es ist bekannt, dass viele Server ISO-8859-1 verwenden (ob es Ihnen gefällt oder nicht) und fehlschlagen, wenn Sie etwas anderes senden. Daher ist es wahrscheinlich die einzig sichere Wahl, sich an ASCII zu halten.

Weitere Informationen und einen Vorschlag zur Behebung der Situation finden Sie im Entwurf "Ein Codierungsparameter für die HTTP-Basisauthentifizierung" (der die Grundlage für RFC 7617 bildete).

Neu - RFC 7617

Seit 2015 gibt es RFC 7617 , das RFC 2617 überholt. Im Gegensatz zum alten RFC definiert der neue RFC explizit die Zeichenkodierung, die für Benutzername und Passwort verwendet werden soll.

  • Die Standardcodierung ist noch undefiniert. Is muss nur mit US-ASCII kompatibel sein (dh es ordnet ASCII-Bytes wie UTF-8 ASCII-Bytes zu).
  • Der Server kann charset="UTF-8"in seiner Abfrage optional einen zusätzlichen Authentifizierungsparameter senden , wie
    WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
    folgt : Dies gibt an, dass der Server Nicht-ASCII-Zeichen in Benutzername / Kennwort akzeptiert und erwartet, dass diese in UTF-8 (insbesondere Normalisierungsformular C) codiert werden. . Beachten Sie, dass nur UTF-8 zulässig ist.

Vollversion:

Lesen Sie die Spezifikation . Enthält zusätzliche Details wie das genaue Codierungsverfahren und die Liste der zu unterstützenden Unicode-Codepunkte.

Browser-Unterstützung

Ab 2018 verwenden moderne Browser normalerweise standardmäßig UTF-8, wenn ein Benutzer Nicht-ASCII-Zeichen für Benutzername oder Kennwort eingibt (auch wenn der Server den charsetParameter nicht verwendet ).

  • Chrome scheint auch UTF-8 zu verwenden
  • Internet Explorer verwendet UTF-8 nicht ( Problem # 11879588 )
  • Firefox experimentiert mit einer Änderung, die derzeit für Version 59 geplant ist ( Fehler 1419658 ).

Reich

Der Realm- Parameter unterstützt auch in RFC 7617 nur ASCII-Zeichen.

Julian Reschke
quelle
Danke Julian. Ich war auf diesen Vorschlag gestoßen, scheint aber abgelaufen zu sein und nicht weiter gegangen zu sein. Schade :-(.
Dobes Vandermeer
1
Ihre Antwort muss die beste sein. Ich kann es mit Sicherheit als ASCII umschreiben, vielleicht ISO-8859-1, wenn Sie Glück haben.
Dobes Vandermeer
Es sieht so aus, als ob die neueste Version 04 des Vorschlags (die zufällig heute veröffentlicht zu werden scheint) am 1. August 2012 abläuft.
Michiel van Oosterhout
Die Antwort war veraltet, da RFC 7617 nicht erwähnt wurde. Ich habe sie bearbeitet, um sie einzuschließen. Julian: Ich hoffe es macht dir nichts aus.
Sleske
Hoppla - Ich habe gerade festgestellt, dass Sie tatsächlich der Autor von RFC 7617 sind. Jetzt hoffe ich wirklich, dass ich etwas nicht falsch bearbeitet habe.
Sleske
41

Kurze Antwort: iso-8859-1, sofern keine codierten Wörter gemäß RFC2047 (MIME) verwendet werden.

Längere Erklärung:

RFC2617, Abschnitt 2 (HTTP-Authentifizierung) definiert grundlegende Anmeldeinformationen :

basic-credentials = base64-user-pass
base64-user-pass  = <base64 encoding of user-pass, 
                     except not limited to 76 char/line>
user-pass         = userid ":" password
userid            = *<TEXT excluding ":">
password          = *TEXT

Die Spezifikation sollte nicht gelesen werden, ohne auf RFC2616 (HTTP 1.1) für Definitionen in BNF (wie oben) zu verweisen:

Diese Spezifikation ist eine Ergänzung zur HTTP / 1.1-Spezifikation 2 . Es verwendet den erweiterten BNF-Abschnitt 2.1 dieses Dokuments und stützt sich sowohl auf die in diesem Dokument definierten Nicht-Terminals als auch auf andere Aspekte der HTTP / 1.1-Spezifikation.

RFC2616, Abschnitt 2.1 definiert TEXT (Schwerpunkt Mine):

Die TEXT-Regel wird nur für beschreibende Feldinhalte und Werte verwendet, die nicht vom Nachrichtenparser interpretiert werden sollen. Wörter von * TEXT KÖNNEN Zeichen aus anderen Zeichensätzen als ISO-8859-1 nur enthalten, wenn sie gemäß den Regeln von RFC 2047 codiert sind.

TEXT           = <any OCTET except CTLs, but including LWS>

Es ist also definitiv iso-8859-1, es sei denn, Sie erkennen eine andere Codierung gemäß den RFC2047- Regeln (MIME Punkt 3):

// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=

In diesem Fall würde das Euro-Zeichen im Wort 0xA4gemäß ISO-8859-15 codiert . Nach meinem Verständnis sollten Sie nach diesen codierten Worttrennzeichen suchen und dann die darin enthaltenen Wörter basierend auf der angegebenen Codierung decodieren. Wenn Sie dies nicht tun, denken Sie, dass das Passwort lautet =?iso-8859-15?q?T¤ST?=(Hinweis, 0xA4der ¤bei der Interpretation als iso-8859-1 dekodiert wird ).

Nach meinem Verständnis kann ich keine explizitere Bestätigung finden als diese RFCs. Und einiges davon scheint widersprüchlich. Eines der vier erklärten Ziele von RFC2047 (MIME, Punkt 3) ist beispielsweise die Neudefinition von:

Das Format der Nachrichten, um ... Text-Header-Informationen in anderen Zeichensätzen als US-ASCII zu ermöglichen.

Dann definiert RFC2616 (HTTP 1.1) einen Header unter Verwendung der TEXT-Regel, die standardmäßig iso-8859-1 ist. Bedeutet das, dass jedes Wort in dieser Kopfzeile ein verschlüsseltes Wort sein sollte (dh die =?...?=Form)?

Ebenfalls relevant ist, dass dies kein aktueller Browser tut. Sie verwenden utf-8 (Chrome, Opera), iso-8859-1 (Safari), die Systemcodepage (IE) oder etwas anderes (wie nur das wichtigste Bit von utf-8 im Fall von Firefox).

Bearbeiten: Ich habe gerade festgestellt, dass diese Antwort das Problem eher aus der serverseitigen Perspektive betrachtet.

Michiel van Oosterhout
quelle
Die RFC 2047-Codierung gilt in diesem Fall nicht.
Julian Reschke
@JulianReschke Nun, die Spezifikation besagt eindeutig "nur wenn sie gemäß den Regeln von RFC 2047 codiert ist". Ich verstehe, dass die Regeln in RFC2047 möglicherweise nicht auf HTTP-Header anwendbar sind, aber die Spezifikation ist ziemlich klar, wenn man darauf verweist. Ich habe die Tatsache hinzugefügt, dass kein Browser dies tatsächlich tut.
Michiel van Oosterhout
4
In den HTTPbis-Spezifikationen wird RFC 2047 nicht mehr erwähnt.
Julian Reschke
Sehr ausführlicher Artikel, danke @MichielvanOosterhout!
ToastyMallows
5

Abgesehen von RFCs ist in Spring Framework , der BasicAuthenticationFilterKlasse, der Standard UTF-8 .

Ich glaube, der Grund für diese Wahl ist, dass UTF-8 alle möglichen Zeichen codieren kann, ISO-8859-1 (oder ASCII) jedoch nicht. Der Versuch, Benutzername / Passwort mit Zeichen zu verwenden, die im System nicht unterstützt werden, kann zu fehlerhaftem Verhalten oder (möglicherweise schlimmer) zu einer Verschlechterung der Sicherheit führen.

holmis83
quelle
1
Die Verwendung von UTF-8 hilft nicht, wenn die andere Seite nichts davon weiß. Es wäre also gut, wenn das Spring-Framework den in < greenbytes.de/tech/webdav/rfc7617.html#rfc.section.2.1 >
Julian Reschke,
1
@JulianReschke Ich informierte, wie es in einem der gängigsten Frameworks implementiert wird und ein wahrscheinlicher Grund dafür. Erschieße nicht den Boten!
holmis83
4

Wenn Sie daran interessiert sind, was Browser tun, wenn Sie an der Anmeldeaufforderung Nicht-ASCII-Zeichen eingeben, habe ich es gerade mit Firefox versucht.

Es scheint träge alles in ISO-8859-1 umzuwandeln, indem das niedrigstwertige Byte jedes Unicode-Werts verwendet wird, z.

User: 豚 (\u8c5a)
Password: 虎 (\u864e)

Sind wie folgt codiert:

User: Z (\u005a)
Password: N (\u004e)

0x5a 0x3a 0x4e base64-> WjpO

anda apterus
quelle
1
Ja, das ist das alte Verhalten in Firefox. Es wurde geändert (anscheinend in V57) und verwendet jetzt stattdessen UTF-8.
Sleske
1
V59, nicht V57. Derzeit im Beta-Test.
Julian Reschke