2011-08-30 79 views
55

RFC2617表示要將用戶名和密碼編碼爲base64,但不要說創建輸入到base64算法中的八位字節時使用什麼字符編碼。我應該使用什麼編碼進行HTTP基本驗證?

我應該假設US-ASCII或UTF8?或者有人已經在某個地方解決了這個問題?

+1

UTF8)。忘記ASCII – TheHorse

+14

@TheHorse比這更加複雜,不幸的是。 –

+2

相關:[HTTP頭應該使用什麼字符編碼?](http://stackoverflow.com/questions/4400678/http-header-should-use-what-c​​haracter-encoding) –

回答

39

原始規範 - RFC 2617

RFC 2617可以讀作 「ISO-8859-1」 或 「不確定」。你的選擇。衆所周知,許多服務器使用ISO-8859-1(喜歡與否),並且在發送其他內容時會失敗。所以可能唯一安全的選擇是堅持ASCII。

有關更多信息和解決方案的建議,請參閱草稿"An Encoding Parameter for HTTP Basic Authentication"(它構成RFC 7617的基礎)。

新 - RFC 7617

由於2015年有RFC 7617,它淘汰了RFC 2617相較於老RFC,新的RFC明確定義的字符編碼用於用戶名和密碼。

  • 默認編碼仍未定義。只需要與US-ASCII兼容(意味着它將ASCII字節映射到ASCII字節,就像UTF-8一樣)。
  • 服務器可以任選以其挑戰發送額外的認證參數charset="UTF-8",像這樣:
    WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
    此宣佈,服務器將接受用戶名/密碼非ASCII字符,並預計他們在編碼UTF-8(特別是標準化表格C)。請注意,只允許使用UTF-8。

完整版:

the spec。如果包含其他詳細信息(如確切的編碼過程)以及應支持的Unicode代碼點列表。

瀏覽器支持

截至2018年,如果用戶的用戶名和密碼(即使服務器不使用charset參數)進入非ASCII字符的現代瀏覽器通常會默認爲UTF-8。

改變試驗領域

領域參數仍然只支持ASCII字符,即使在RFC 7617中。

+0

謝謝朱利安。我遇到了這個提案,但似乎已經過期,並且沒有更進一步。太糟糕了:-( –

+1

你的答案肯定是最好的,我可以解釋爲ASCII,如果你幸運的話也許是ISO-8859-1 –

+0

看起來像[提案的最新版本04](http: //tools.ietf.org/html/draft-reschke-basicauth-enc-04)(其中巧合似乎今天發佈)於2012年8月1日到期。 –

33

簡短回答:iso-8859-1,除非按照RFC2047(MIME)使用編碼字。

較長的解釋:

RFC2617, section 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 

該規範不應該不參照RFC2616被讀取(HTTP 1.1),用於在BNF定義(像上面的那個):

本規範是HTTP/1.1規範2的配套。 它使用該文檔的增強的BNF部分2.1,並且依賴於該文檔中定義的非終端和HTTP/1.1規範的其他方面的 。

RFC2616, section 2.1限定TEXT(重點煤礦):

的TEXT規則僅用於描述性字段內容和值 不打算由消息解析器來解釋。 * TEXT的話 可能包含字符從字符集等比 ISO-8859-1只有當按照RFC規則編碼2047

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

所以它肯定是ISO-8859-1,除非你根據RFC2047檢測一些其他編碼規則(MIME PT 3):

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

在這種情況下,在字中的歐元符號將根據被編碼爲0xA4 210。這是我的理解,你應該檢查這些編碼的單詞分隔符,然後根據指定的編碼解碼內部的單詞。如果你不這樣做,你會認爲密碼是=?iso-8859-15?q?T¤ST?=(注意當解釋爲iso-8859-1時,0xA4將被解碼爲¤)。

這是我的理解,我找不到比這些RFC更明確的確認。其中有些似乎是矛盾的。例如,4中的一個表示RFC2047的目標(MIME,PT 3)是重新定義:

消息以允許在...字符 文本標題信息的格式比US-ASCII設置其他。

但是然後RFC2616(HTTP 1.1)使用默認爲iso-8859-1的TEXT規則定義了一個頭文件。這是否意味着該標題中的每個詞都應該是一個編碼詞(即=?...?=表單)?

同樣相關的,沒有當前的瀏覽器這樣做。他們使用utf-8(Chrome,Opera),iso-8859-1(Safari),系統代碼頁(IE)或其他東西(例如Firefox中僅有的來自utf-8的最重要的位)。

編輯:我剛剛意識到這個答案更多地從服務器端角度來看問題。

+0

RFC 2047編碼不適用在這種情況下 –

+0

@JulianReschke那麼,規範明確指出「只有在根據RFC 2047的規則進行編碼時」,我明白RFC2047中的規則可能不適用於HTTP頭文件,但該規範在提及它時非常明確我已經添加了事實上,沒有瀏覽器實際上這樣做。 –

+3

HTTPbis規範將不再提及RFC 2047。 –

3

如果您對在登錄提示時輸入非ascii字符時瀏覽器執行什麼操作感興趣,我只是嘗試使用Firefox。

看來,抓住每一個Unicode值的最低顯著字節,例如,懶洋洋地everithing轉換爲ISO-8859-1:

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

編碼一樣:

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

0x5a 0x3a 0x4e base64-> WjpO

+0

是的,這是Firefox中的舊行爲。它被改變了(在V57中,似乎),現在使用UTF-8。 – sleske

+0

V59,而不是V57。目前正在進行beta測試。 –

3

RFCCs擱置,在彈簧框架,BasicAuthenticationFilter類,默認是UTF-8

我相信這種選擇的原因是UTF-8能夠編碼所有可能的字符,而ISO-8859-1(或ASCII)則不能。嘗試使用系統中不支持字符的用戶名/密碼可能會導致行爲中斷或(可能更糟糕)降低安全性。

+0

那麼,如果對方不知道使用UTF-8就沒有幫助。因此,如果Spring框架實現了

+1

@JulianReschke中介紹的charset參數,我會告訴你它是如何在其中一個實現的最常見的框架及其可能的原因。不要拍攝使者! – holmis83

相關問題