Django 自带密码加密,自定密码加密方式 及自定义验证方式
在django1.6中,默认的加密方式是pbkdf_sha256,具体算法不表,一直以来用django的自带用户验证都十分顺手,今天有需求,需要修改默认加密方式为md5,具体方法为:
在settings.py中加入
[python] view plain copy print?- PASSWORD_HASHERS = (
- 'myproject.hashers.MyMD5PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- '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.CryptPasswordHasher',
- )
PASSWORD_HASHERS = ( 'myproject.hashers.MyMD5PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher', '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.CryptPasswordHasher', )
django会默认使用第一条加密方式。
这个是我自定义的加密方式,就是基本的md5,而django的MD5PasswordHasher是加盐的。
以下是我的自定义hashers.py:
[python] view plain copy print?
- 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)),
- ])
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)), ])之后可以在数据库中看到,密码确实使用了自定义的加密方式。
然而仅仅修改这些,在配合django的authenticate验证时无法进行。
经过一些查找,发现需要在自定义authenticate。以下为方法:
在settings.py中加入以下:
[python] view plain copy print?
- AUTHENTICATION_BACKENDS = (
- 'chicken.mybackend.MyBackend',
- )
AUTHENTICATION_BACKENDS = ( 'chicken.mybackend.MyBackend', )以下代码为自定义的mybackend.py
[python] view plain copy print?
- import hashlib
- from pro import models
- class MyBackend(object):
- 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
import hashlib from pro import models class MyBackend(object): 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自带的降低很多,但是需求就是这样的,必须满足。
完成需求的过程中查找了不少资料,最后还是在django文档中找到的答案,文档还是很全全面的,以后通读还是感觉有必要的。
考虑到Django有用户验证模块,证明它已具备跨平台的加密模块。
首先,引入模块:
代码如下 | 复制代码 |
>>> from django.contrib.auth.hashers import make_password, check_password
生成密码: |
这样就可以利用django自带的模块生成一组密码了,这个函数还有一个特点在于每次生成的密码还不一样:
代码如下 | 复制代码 |
|
既然每次生成的密文都不一样,如何验证用户提交过来的明文与密文匹配呢?这就靠check_password去做了,check_password使用非常简单,只需要告诉它明文和密文它就会返回False or True验证结果
代码如下 | 复制代码 |
|
如果你不想每次都生成不同的密文,可以把make_password的第二个函数给一个固定的字符串,比如:
代码如下 | 复制代码 |
>>> make_password(text, "a", 'pbkdf2_sha256') u'pbkdf2_sha256$12000$a$5HkIPczRZGSTKUBa5uzZmRuAWdp2Qe6Oemhdasvzv4Q=' >>> make_password(text, "a", 'pbkdf2_sha256') u'pbkdf2_sha256$12000$a$5HkIPczRZGSTKUBa5uzZmRuAWdp2Qe6Oemhdasvzv4Q=' |
只要是任意字符串就可以,并且可以多个。但不能为空,如:
代码如下 | 复制代码 |
|
为空的字符串就相当于:
1
代码如下 | 复制代码 |
make_password(text, None, 'pbkdf2_sha256') |
至于make_password第三个参数是表示生成密文的一种方式,根据文档给出的大概有这几种:
代码如下 | 复制代码 |
pbkdf2_sha256 |
以上例子我使用了第一种加密方式pbkdf2_sha256,crypt和bcrypt都需要另外单独安装模块,unsalted_md5就是常见的md5加密,如果对加密哈希算法不是很了解,那么就使用django最新的哈希算法pbkdf2_sha256就好
- django 自定义 密码加密方式 及自定义验证方式
- django 自定义 密码加密方式 及自定义验证方式
- 一个流行且实用的JS表单验证提示,演示了怎么自定义错误信息的显示方式,同时通过写FormValid.showError类方法来实现错误显示方式自定义: errMsg 是一个错误消息的数组,这样方便自定
- django实现密码加密的注册(数据对象插入)-结合forms表单实现表单验证
- django项目培训站-17-用户登陆-自定义用户验证方式-错误提示信息传前端
- Cas单点登录(5)数据库验证用户之自定义密码加密
- 单点登录(十五)-----实战-----cas4.2.x登录mongodb验证方式实现自定义加密
- 单点登录(十五)-----实战-----cas4.2.x登录mongodb验证方式实现自定义加密
- django学习——用户注册时的密码加密及登陆时的密码验证问题
- shiro自定义密码匹配验证,密码加密验证。
- Joomla登录验证,密码加密方式
- 将现有系统用户密码转为.text加密方式的密码
- MOSS 之 自定义MembershipProvider实现Forms方式验证
- cisco设备密码配置方法及加密方式详解
- WCF分布式安全开发实践(3):传输安全模式之自定义用户名密码身份验证:Transport_UserNamePassword_WSHttpBinding
- DNN中自定义密码验证
- 浅谈系统密码加密方式
- Django 类方式view进行进行用户验证
- 密码加密的最好方式
- 修改cas-server(三),自定义登录验证方式。