2016-05-20 26 views
2

我使用春季啓動,春季mvc和春季安全,使一個簡單的網站。在登錄頁面中,我有一個記住我的複選框。當它被打勾並登錄時,爲瀏覽器創建一個記憶我的cookie。我已經嘗試了Chrome和Firefox。春季安全記得我的cookie Unicode字符錯誤

該cookie位於下方。

Name: remember-me 
Content: Pz8/Pz8/OjE0NjQ5ODcxMjQxMDk6YTc1MDMzNTM0ZmNhNjc3YmUwOTljZGNjN2EyYTk1NjM 
Domain: localhost 
Path: /gy 
Send For: Any kind of connection 
Accessible to Script: No (HttpOnly) 
Created: Friday, 20 May 2016 at 21:52:04 
Expires: Friday, 3 June 2016 at 21:52:04 

以上內容是base64格式。解碼後的字符串如下。

??????:1464987124109:a75033534fca677be099cdcc7a2a9563

第一部分是用戶名是中國字符,但顯示爲??????。

我知道要將Unicode字符保存到cookie中,我們應該先使用URLEncoder類對其進行編碼,然後在讀取它之後對其進行解碼。我是Java和Spring的新手,所以不知道如何自定義記住我的cookie來處理Unicode字符。

任何線索來解決這個問題將不勝感激。謝謝!

回答

2

這是Spring Security中的一個錯誤。使用的getBytes 0參數版本,其編碼的Unicode字符,使用默認的編碼字節

Hex.encode(digest.digest(data.getBytes())); 

:它計算MD5 like this。默認編碼各不相同,但在您的服務器上明顯是不包含中文字符的編碼。

永遠不要依賴默認編碼。它通常不是一個UTF,所以不能包含所有的Unicode字符。此外,由於它不是固定的,因此當您從一臺服務器移動到另一臺服務器時,它可能會破壞您的令牌。 Spring應該設置明確的UTF編碼,例如getBytes("UTF-8")

這不是唯一的財產記得,我說讓我擔心:

  • 它使用MD5,散列算法,這是早已過去的素數,且越來越容易受到攻擊。它甚至沒有使用HMAC-MD5這將緩解這一(HMAC設計出於這樣的目的)

  • 所有不支持的字符得到默默地壓扁成相同的字符,?,這意味着對於用戶你好哈希會與用戶☃☃的散列相同。因此理論上可以以用戶名(或問號本身!)中具有不受支持字符的任何受害者用戶身份登錄,通過在其用戶名中創建具有不同不受支持字符的另一用戶,然後改變cookie將受害者用戶名與新用戶的散列一起包含在內。 (但實際上,(a)散列中'密碼'字段的存在使事情複雜化,儘管它也容易被Unicode字符壓扁,並且(b)幸運的是,cookie本身也被錯誤地使用默認編碼解碼,一個從任意Unicode字符首先進入檢查器)。

  • 一起拋出字符串沒有任何轉義符,這樣的怪事發生在組件在,你可能真的不能做太多直接與攻擊的冒號,但它是shonky和attempt to work around it是光榮半arsed 。

我不會相信這段代碼來保護我的web應用程序;在高調的安全庫中看到這種事情令人失望。

+0

謝謝你的出色答案。與用戶的便利性相比,安全性並不是這個網絡應用的一大問題。正如你所建議的,我絕對不會在企業網站中使用這個功能。在Spring團隊修復此錯誤之前,有什麼方法可以解決這個問題,即讓我記得我爲unicode工作? – weijun

+1

您可以嘗試將服務器上的默認編碼設置爲UTF-8,以便可以訪問所有字符。這可以通過將'-Dfile.encoding = UTF8'作爲選項傳遞給Java運行時來完成;你如何設置取決於你使用的容器/操作系統。 – bobince

+0

我已將默認編碼更改爲我的開發PC上的UTF-8,並且工作正常!令人驚訝的是,我的Linux服務器的默認編碼已經是UTF-8,所以它可以直接使用。感謝您的幫助。 – weijun