HTTP基本認証にはどのエンコーディングを使用する必要がありますか?


84

RFC2617は、ユーザー名とパスワードをbase64にエンコードすると述べていますが、base64アルゴリズムへの入力用のオクテットを作成するときに使用する文字エンコードについては述べていません。

US-ASCIIまたはUTF8を想定する必要がありますか?または、誰かがこの質問をすでにどこかで解決しましたか?


回答:


72

元の仕様-RFC2617

RFC 2617は、「ISO-8859-1」または「undefined」として読み取ることができます。あなたの選択。多くのサーバーはISO-8859-1を使用しており(好むと好まざるとにかかわらず)、他のものを送信すると失敗することが知られています。したがって、おそらく唯一の安全な選択はASCIIに固執することです。

詳細および状況を修正するための提案については、ドラフト「HTTP基本認証のエンコーディングパラメータ」(RFC 7617の基礎を形成)を参照してください。

新規-RFC7617

2015年以降、RFC2617を廃止するRFC7617があります。古いRFCとは対照的に、新しいRFCは、ユーザー名とパスワードに使用される文字エンコードを明示的に定義します。

  • デフォルトのエンコーディングはまだ定義されていません。US-ASCIIとの互換性が必要なだけです(つまり、UTF-8のようにASCIIバイトをASCIIバイトにマップします)。
  • サーバーは、オプションでcharset="UTF-8"、次のようにチャレンジで追加の認証パラメーターを送信できます。
    WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
    これは、サーバーがユーザー名/パスワードで非ASCII文字を受け入れ、UTF-8(具体的には正規化フォームC)でエンコードされることを期待していることを通知します。 。UTF-8のみが許可されていることに注意してください。

完全版:

仕様をお読みください。正確なエンコード手順やサポートする必要のあるUnicodeコードポイントのリストなど、追加の詳細が含まれている場合。

ブラウザのサポート

2018年の時点で、ユーザーがユーザー名またはパスワードに非ASCII文字を入力した場合(サーバーがcharsetパラメーターを使用しない場合でも)、最新のブラウザーは通常、デフォルトでUTF-8になります。

  • ChromeもUTF-8を使用しているようです
  • Internet ExplorerはUTF-8を使用しません(問題#11879588
  • Firefoxは、現在v59で計画されている変更を実験しています(バグ1419658)。

レルム

レルムパラメータはまだだけでもRFC 7617にASCII文字をサポートしています。


ジュリアンに感謝します。私はその提案に出くわしましたが、期限切れになり、それ以上どこにも行かなかったようです。残念:
。– Dobes Vandermeer 2011

1
あなたの答えは最高でなければなりません。確かにASCIIと言い換えることができます。運が良ければISO-8859-1かもしれません。
Dobes Vandermeer 2011

ように見え提案の最新バージョン04(偶然にも今日公開されているようです)8月1日に期限が切れる2012年、
ミシェルバンオーステルハウト

RFC 7617について言及されていなかったため、回答は廃止されました。これを含めるように編集しました。ジュリアン:気にしないでください。
sleske

おっと-あなたが実際にRFC7617の作成者であることに気づきました。今、私が何かを誤って編集しなかったことを本当に望んでいます。
sleske

41

簡単な答え:RFC2047(MIME)に従ってエンコードされた単語が使用されていない限り、iso-8859-1。

より長い説明:

RFC2617、セクション2(HTTP認証)は基本認証情報を定義します

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

BNF(上記のような)の定義については、RFC2616(HTTP 1.1)を参照せずに仕様を読むべきではありません。

この仕様は、HTTP /1.1仕様2のコンパニオンです。そのドキュメントの拡張BNFセクション2.1を使用し、そのドキュメントで定義されている非終端記号とHTTP /1.1仕様の他の側面の両方に依存しています。

RFC2616、セクション2.1TEXT(強調鉱山)を定義しています:

TEXTルールは、メッセージパーサーによる解釈を意図していない記述フィールドの内容と値にのみ使用されます。* TEXTの単語には、RFC 2047の規則に従ってエンコードされた場合にのみ、ISO-8859-1以外の文字セットの文字が含ま れる場合があります。

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

したがって、RFC2047MIMEpt。3)の規則に従って他のエンコーディングを検出しない限り、これは間違いなくiso-8859-1です。

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

この場合、単語のユーロ記号は、iso-8859-150xA4に従ってエンコードされます。これらのエンコードされた単語区切り文字を確認してから、指定されたエンコードに基づいて内部の単語をデコードする必要があることを理解しています。そうしないと、パスワードは次のようになります(にデコードされることに注意してください)=?iso-8859-15?q?T¤ST?=0xA4¤ iso-8859-1として解釈とき)。

これは私の理解です。これらのRFCよりも明確な確認を見つけることはできません。そしてそれのいくつかは矛盾しているようです。たとえば、RFC2047(MIME、pt。3)の4つの目標の1つは、次のことを再定義することです。

US-ASCII以外の文字セットのテキストヘッダー情報を許可するメッセージの形式。

ただし、RFC2616(HTTP 1.1)は、デフォルトでiso-8859-1であるTEXTルールを使用してヘッダーを定義します。これは、このヘッダー内のすべての単語がエンコードされた単語である必要があることを意味します(つまり、=?...?=フォーム)であるますか?

また、現在のブラウザはこれを行いません。それらは、utf-8(Chrome、Opera)、iso-8859-1(Safari)、システムコードページ(IE)、またはその他のもの(Firefoxの場合のutf-8の最上位ビットのみなど)を使用します。

編集:私は、この回答がサーバー側の観点から問題をより詳しく見ていることに気づきました。


この場合、RFC2047エンコーディングは適用されません。
ジュリアンレシュケ2012年

@JulianReschkeええと、仕様には「RFC2047の規則に従ってエンコードされた場合のみ」と明記されています。RFC2047のルールがHTTPヘッダーに適用されない可能性があることは理解していますが、仕様はそれを参照する上でかなり明確です。実際にこれを行うブラウザはないという事実を追加しました。
Michiel van Oosterhout 2012年

4
HTTPbis仕様ではRFC2047については言及されなくなりました。
ジュリアンレシュケ2012年

非常に詳細な記事、@ MichielvanOosterhoutに感謝します!
ToastyMallows 2016

5

RFCは別として、SpringフレームワークBasicAuthenticationFilterクラスでは、デフォルトはUTF-8です。

この選択の理由は、UTF-8はすべての可能な文字をエンコードできるのに対し、ISO-8859-1(またはASCII)はエンコードできないためです。システムでサポートされていない文字でユーザー名/パスワードを使用しようとすると、動作が壊れたり、(さらに悪いことに)セキュリティが低下したりする可能性があります。


1
ええと、反対側がそれについて知らなければ、UTF-8を使用することは役に立ちません。したがって、Springフレームワークが< greenbytes.de/tech/webdav/rfc7617.html#rfc.section.2.1 >で説明されているcharsetパラメーターを実装するとよいでしょう
Julian Reschke 2017

1
@JulianReschke最も一般的なフレームワークの1つにどのように実装されているか、そしてその理由として考えられることをお知らせしました。メッセンジャーを撃つな!
holmis83 2017

4

ログインプロンプトでASCII以外の文字を入力したときにブラウザがどのように動作するかに興味がある場合は、Firefoxで試してみました。

各Unicode値の最下位バイトを取得することにより、everithingをISO-8859-1に遅延変換するようです。例:

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

次と同じようにエンコードされます:

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

0x5a 0x3a 0x4e base64-> WjpO


1
はい、それはFirefoxの古い動作です。変更され(V57ではそう思われます)、代わりにUTF-8を使用するようになりました。
sleske

1
V57ではなくV59。現在ベータテスト中です。
ジュリアンレシュケ2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.