一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Django密碼存儲策略分析

Django密碼存儲策略分析

2020-05-01 10:20藍綠色~菠菜 Python

這篇文章主要介紹了Django密碼存儲策略分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、源碼分析

Django 發布的 1.4 版本中包含了一些安全方面的重要提升。其中一個是使用 PBKDF2 密碼加密算法代替了 SHA1 。另外一個特性是你可以添加自己的密碼加密方法。

Django 會使用你提供的第一個密碼加密方法(在你的 setting.py 文件里要至少有一個方法)

?
1
2
3
4
5
6
7
PASSWORD_HASHERS = [
  'django.contrib.auth.hashers.PBKDF2PasswordHasher',
  'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
  'django.contrib.auth.hashers.Argon2PasswordHasher',
  'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
  'django.contrib.auth.hashers.BCryptPasswordHasher',
]

我們先一睹自帶的PBKDF2PasswordHasher加密方式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class BasePasswordHasher(object):
  """
  Abstract base class for password hashers
  When creating your own hasher, you need to override algorithm,
  verify(), encode() and safe_summary().
  PasswordHasher objects are immutable.
  """
  algorithm = None
  library = None
 
  def _load_library(self):
    if self.library is not None:
      if isinstance(self.library, (tuple, list)):
        name, mod_path = self.library
      else:
        name = mod_path = self.library
      try:
        module = importlib.import_module(mod_path)
      except ImportError:
        raise ValueError("Couldn't load %s password algorithm "
                 "library" % name)
      return module
    raise ValueError("Hasher '%s' doesn't specify a library attribute" %
             self.__class__)
 
  def salt(self):
    """
    Generates a cryptographically secure nonce salt in ascii
    """
    return get_random_string()
 
  def verify(self, password, encoded):
    """
    Checks if the given password is correct
    """
    raise NotImplementedError()
 
  def encode(self, password, salt):
    """
    Creates an encoded database value
    The result is normally formatted as "algorithm$salt$hash" and
    must be fewer than 128 characters.
    """
    raise NotImplementedError()
 
  def safe_summary(self, encoded):
    """
    Returns a summary of safe values
    The result is a dictionary and will be used where the password field
    must be displayed to construct a safe representation of the password.
    """
    raise NotImplementedError()
 
 
class PBKDF2PasswordHasher(BasePasswordHasher):
  """
  Secure password hashing using the PBKDF2 algorithm (recommended)
  Configured to use PBKDF2 + HMAC + SHA256.
  The result is a 64 byte binary string. Iterations may be changed
  safely but you must rename the algorithm if you change SHA256.
  """
  algorithm = "pbkdf2_sha256"
  iterations = 36000
  digest = hashlib.sha256
 
  def encode(self, password, salt, iterations=None):
    assert password is not None
    assert salt and '$' not in salt
    if not iterations:
      iterations = self.iterations
    hash = pbkdf2(password, salt, iterations, digest=self.digest)
    hash = base64.b64encode(hash).decode('ascii').strip()
    return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
 
  def verify(self, password, encoded):
    algorithm, iterations, salt, hash = encoded.split('$', 3)
    assert algorithm == self.algorithm
    encoded_2 = self.encode(password, salt, int(iterations))
    return constant_time_compare(encoded, encoded_2)
 
  def safe_summary(self, encoded):
    algorithm, iterations, salt, hash = encoded.split('$', 3)
    assert algorithm == self.algorithm
    return OrderedDict([
      (_('algorithm'), algorithm),
      (_('iterations'), iterations),
      (_('salt'), mask_hash(salt)),
      (_('hash'), mask_hash(hash)),
    ])
 
  def must_update(self, encoded):
    algorithm, iterations, salt, hash = encoded.split('$', 3)
    return int(iterations) != self.iterations
 
  def harden_runtime(self, password, encoded):
    algorithm, iterations, salt, hash = encoded.split('$', 3)
    extra_iterations = self.iterations - int(iterations)
    if extra_iterations > 0:
      self.encode(password, salt, extra_iterations)

正如你看到那樣,你必須繼承自BasePasswordHasher,并且重寫 verify() , encode() 以及 safe_summary() 方法。

Django 是使用 PBKDF 2算法與36,000次的迭代使得它不那么容易被暴力破解法輕易攻破。密碼用下面的格式儲存:

algorithm$number of iterations$salt$password hash”

例:pbkdf2_sha256$36000$Lx7auRCc8FUI$eG9lX66cKFTos9sEcihhiSCjI6uqbr9ZrO+Iq3H9xDU=

二、自定義密碼加密方法

1、在settings.py中加入自定義的加密算法:

?
1
2
3
4
5
6
7
8
PASSWORD_HASHERS = [
  'myproject.hashers.MyMD5PasswordHasher',
  'django.contrib.auth.hashers.PBKDF2PasswordHasher',
  'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
  'django.contrib.auth.hashers.Argon2PasswordHasher',
  'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
  'django.contrib.auth.hashers.BCryptPasswordHasher',
]

2、再來看MyMD5PasswordHasher,這個是我自定義的加密方式,就是基本的md5,而django的MD5PasswordHasher是加鹽的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.contrib.auth.hashers import BasePasswordHasher,MD5PasswordHasher
from django.contrib.auth.hashers import mask_hash
import hashlib
 
class MyMD5PasswordHasher(MD5PasswordHasher):
  algorithm = "mymd5"
 
  def encode(self, password, salt):
    assert password is not None
    hash = hashlib.md5(password).hexdigest().upper()
    return hash
 
  def verify(self, password, encoded):
    encoded_2 = self.encode(password, '')
    return encoded.upper() == encoded_2.upper()
 
  def safe_summary(self, encoded):
    return OrderedDict([
        (_('algorithm'), algorithm),
        (_('salt'), ''),
        (_('hash'), mask_hash(hash)),
        ])

之后可以在數據庫中看到,密碼確實使用了自定義的加密方式。

3、修改認證方式

?
1
2
3
4
5
AUTHENTICATION_BACKENDS = (
  'framework.mybackend.MyBackend', #新加
  'django.contrib.auth.backends.ModelBackend',
  'guardian.backends.ObjectPermissionBackend',
)

4、再來看自定義的認證方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
framework.mybackend.py:
 
 import hashlib
 from pro import models
 from django.contrib.auth.backends import ModelBackend
 
 class MyBackend(ModelBackend):
   def authenticate(self, username=None, password=None):
     try:
       user = models.M_User.objects.get(username=username)
       print user
     except Exception:
       print 'no user'
       return None
     if hashlib.md5(password).hexdigest().upper() == user.password:
       return user
     return None
 
   def get_user(self, user_id):
     try:
       return models.M_User.objects.get(id=user_id)
     except Exception:
       return None

當然經過這些修改后最終的安全性比起django自帶的降低很多,但是需求就是這樣的,必須滿足。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/bocai_xiaodaidai/article/details/103872716

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国内体内she精视频免费 | 69热精品视频在线看影院 | 大胆暴露亚洲美女xxxx | 91在线免费看 | www.亚洲视频 | 欧美日本一区视频免费 | 色综合久久中文字幕网 | 天天干夜夜拍 | 果冻传媒天美传媒网址入口 | 任我行视频在线观看国语 | 国产区成人综合色在线 | 新影音先锋男人色资源网 | 视频一区二区三区在线观看 | 91影视在线看免费观看 | 国产福利片在线 | 性色AV乱码一区二区三区视频 | 国产激情久久久久影院小草 | 四虎影院2022| 日本高清无吗 | 金莲一级淫片aaaaaa | 久久精品小视频 | 国产夜趣福利第一视频 | 2019亚洲男人天堂 | 天天爽天天操 | 香蕉成人999视频 | 成人永久免费视频 | 女毛片 | 99精品国产成人一区二区 | 亚洲乱亚洲乱妇41p国产成人 | 午夜在线观看免费完整直播网页 | 3p文两男一女办公室高h | 欧美同志网址 | 成人国产第一区在线观看 | 国产精品香蕉一区二区三区 | 欧美日韩中文字幕在线视频 | 日韩基地1024首页 | 日本xxxxn1819| 天美影视传媒mv直接看 | 久久久无码精品无码国产人妻丝瓜 | 日韩精品福利视频一区二区三区 | 亚洲另类第一页 |