django1.8官方文件翻譯:13-1-3密碼管理

apachecn_飛龍發表於2015-09-20

Django中的密碼管理

密碼管理在非必要情況下一般不會重新發明,Django致力於提供一套安全、靈活的工具集來管理使用者密碼。本文件描述Django儲存密碼和hash儲存方法配置的方式,以及使用hash密碼的一些例項。

另見

即使使用者可能會使用強密碼,攻擊者也可能竊聽到他們的連線。使用HTTPS來避免在HTTP連線上傳送密碼(或者任何敏感的資料),因為否則密碼又被嗅探的風險。

Django如何儲存密碼

Django通常使用PBKDF2來提供靈活的密碼儲存系統。

User 物件的password屬性是一個這種格式的字串:

<algorithm>$<iterations>$<salt>$<hash>

那些就是用於儲存使用者密碼的部分,以美元字元分分隔。它們由雜湊演算法、演算法迭代次數(工作因數)、隨機的salt、以及生成的密碼雜湊值組成。演算法是Django可以使用的,單向雜湊或者密碼儲存演算法之一,請見下文。迭代描述了演算法在雜湊上執行的次數。salt是隨機的種子值,雜湊值是這個單向函式的結果。

通常,Django以SHA256的雜湊值使用PBKDF2演算法,由NIST推薦的一種密碼伸縮機制。這對於大多數使用者都很有效:它非常安全,需要大量的計算來破解。

然而,取決於你的需求,你可以選擇一個不同的演算法,或者甚至使用自定義的演算法來滿足你的特定的安全環境。不過,大多數使用者並不需要這樣做 – 如果你不確定,最好不要這樣。如果你打算這樣做,請繼續閱讀:

DJango通過訪問PASSWORD_HASHERS設定來選擇要使用的演算法。這裡有一個列表,列出了Django支援的雜湊演算法類。列表的第一個元素 (即settings.PASSWORD_HASHERS[0]) 會用於儲存密碼, 所有其它元素都是用於驗證的雜湊值,它們可以用於檢查現有的密碼。意思是如果你打算使用不同的演算法,你需要修改PASSWORD_HASHERS,來將你最喜歡的演算法在列表中放在首位。

PASSWORD_HASHERS預設為:

PASSWORD_HASHERS = (
    `django.contrib.auth.hashers.PBKDF2PasswordHasher`,
    `django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher`,
    `django.contrib.auth.hashers.BCryptSHA256PasswordHasher`,
    `django.contrib.auth.hashers.BCryptPasswordHasher`,
    `django.contrib.auth.hashers.SHA1PasswordHasher`,
    `django.contrib.auth.hashers.MD5PasswordHasher`,
    `django.contrib.auth.hashers.CryptPasswordHasher`,
)

這意味著,Django會使用 PBKDF2 儲存所有密碼,但是支援使用 PBKDF2SHA1, bcrypt, SHA1等等演算法來檢查儲存的密碼。下一節會描述一些通用的方法,高階使用者可能想通過它來修改這個設定。

在Django中使用bcrypt

Bcrypt是一種流行的密碼儲存演算法,它特意被設計用於長期的密碼儲存。Django並沒有預設使用它,由於它需要使用三方的庫,但是由於很多人都想使用它,Django會以最小的努力來支援。

執行以下步驟來作為你的預設儲存演算法來使用Bcrypt:

  1. 安裝bcrypt 庫。這可以通過執行pip install django[bcrypt],,或者下載並執行 python setup.py install來實現。

  2. 修改 PASSWORD_HASHERS ,將 BCryptSHA256PasswordHasher放在首位。也就是說,在你的設定檔案中應該:

    PASSWORD_HASHERS = (
        `django.contrib.auth.hashers.BCryptSHA256PasswordHasher`,
        `django.contrib.auth.hashers.BCryptPasswordHasher`,
        `django.contrib.auth.hashers.PBKDF2PasswordHasher`,
        `django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher`,
        `django.contrib.auth.hashers.SHA1PasswordHasher`,
        `django.contrib.auth.hashers.MD5PasswordHasher`,
        `django.contrib.auth.hashers.CryptPasswordHasher`,
    )
    

    (你應該將其它元素留在列表中,否則Django不能升級密碼;見下文)。

配置完畢 – 現在Django會使用Bcrypt作為預設的儲存演算法。

BCryptPasswordHasher的密碼截斷

bcrypt的設計者會在72個字元處截斷所有的密碼,這意味著bcrypt(password_with_100_chars) == bcrypt(password_with_100_chars[:72])。原生的 BCryptPasswordHasher 並不會做任何的特殊處理, 所以它也會受到這一隱藏密碼長度限制的約束。BCryptSHA256PasswordHasher 通過事先使用 sha256生成雜湊來解決這一問題。這樣就可以防止密碼截斷了,所以你還是應該優先考慮BCryptPasswordHasher。這個截斷帶來的實際效果很微不足道,因為大多數使用者不會使用長度超過72的密碼,並且即使在72個字元處截斷,破解brypt所需的計算能力依然是天文數字。雖然如此,我們還是推薦使用BCryptSHA256PasswordHasher ,根據 “有備無患”的原則。

其它 bcrypt 的實現

有一些其它的bcrypt 實現,可以讓你在Django中使用它。Django的bcrypt 支援並不直接相容這些實現。你需要修改資料庫中的雜湊值,改為 bcrypt$(raw bcrypt output)的形式,來升級它們。例如: bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy

增加工作因數

PBKDF2 和bcrypt 演算法使用大量的雜湊迭代或迴圈。這會有意拖慢攻擊者,使對雜湊密碼的攻擊更難以進行。然而,隨著計算機能力的不斷增加,迭代的次數也需要增加。我們選了一個合理的預設值(並且在Django的每個發行版會不斷增加),但是你可能想要調高或者調低它,取決於你的安全需求和計算能力。要想這樣做,你可以繼承相應的演算法,並且覆寫iterations引數。例如,增加PBKDF2演算法預設使用的迭代次數:

  1. 建立django.contrib.auth.hashers.PBKDF2PasswordHasher的子類:

    from django.contrib.auth.hashers import PBKDF2PasswordHasher
    
    class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
        """
        A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
        """
        iterations = PBKDF2PasswordHasher.iterations * 100
    

    把它儲存在專案中的某個位置。例如,把它放在類似於myproject/hashers.py的檔案中。

  2. 將你的新的hasher作為第一個元素新增到PASSWORD_HASHERS

    PASSWORD_HASHERS = (
        `myproject.hashers.MyPBKDF2PasswordHasher`,
        `django.contrib.auth.hashers.PBKDF2PasswordHasher`,
        `django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher`,
        `django.contrib.auth.hashers.BCryptSHA256PasswordHasher`,
        `django.contrib.auth.hashers.BCryptPasswordHasher`,
        `django.contrib.auth.hashers.SHA1PasswordHasher`,
        `django.contrib.auth.hashers.MD5PasswordHasher`,
        `django.contrib.auth.hashers.CryptPasswordHasher`,
    )
    

配置完畢 – 現在DJango在儲存使用PBKDF2的密碼時會使用更多的迭代次數。

密碼升級

使用者登入之後,如果他們的密碼沒有以首選的密碼演算法來儲存,Django會自動將演算法升級為首選的那個。這意味著Django中舊的安裝會在使用者登入時自動變得更加安全,並且你可以隨意在新的(或者更好的)儲存演算法發明之後切換到它們。

然而,Django只會升級在 PASSWORD_HASHERS中出現的演算法,所以升級到新系統時,你應該確保不要 移除列表中的元素。如果你移除了,使用列表中沒有的演算法的使用者不會被升級。修改PBKDF2迭代次數之後,密碼也會被升級。

Manually managing a user’s password

django.contrib.auth.hashers模組提供了一系列的函式來建立和驗證雜湊密碼。你可以獨立於User模型之外使用它們。

check_password(password, encoded)[source]

如果你打算通過比較純文字密碼和資料庫中雜湊後的密碼來手動驗證使用者,要使用check_password()這一便捷的函式。它接收兩個引數:要檢查的純文字密碼,和資料庫中使用者的password欄位的完整值。如果二者匹配,返回True ,否則返回False

make_password(password, salt=None, hasher=’default’)[source]

以當前應用所使用的格式建立雜湊密碼。它接受一個必需引數:純文字密碼。如果你不想使用預設值(PASSWORD_HASHERS設定的首選項),你可以提供salt值和要使用的雜湊演算法,它們是可選的。當前支援的演算法是: `pbkdf2_sha256`, `pbkdf2_sha1`, `bcrypt_sha256` (參見在 Django中使用Bcrypt), `bcrypt`, `sha1`, `md5`, `unsalted_md5` (僅僅用於向後相容) 和 `crypt` (如果你安裝了 crypt庫)。如果password引數是None,會返回一個不可用的密碼(它永遠不會被check_password()接受)。

is_password_usable(encoded_password)[source]

檢查提供的字串是否是可以用check_password()驗證的雜湊密碼。

譯者:Django 文件協作翻譯小組,原文:Password management

本文以 CC BY-NC-SA 3.0 協議釋出,轉載請保留作者署名和文章出處。

Django 文件協作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。


相關文章