python加密之hashlib

1、强大的hashlib,提供了用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

2、hmac模块实现了hmac算法,需要一个key来进行加密,提供更为强大的加密,不过需要提供key,也就是通常说的盐

3、使用hashlib.algorithms_available,可以查看hashlib提供的加密算法

4、加密的算法的一般使用,但时候存在缺陷,即:通过撞库可以反解

# ######## md5 ########
hash = hashlib.md5()  #创建md5()加密实例
hash.update(bytes('admin', encoding='utf-8'))  #对admin字符进行加密
print(hash.hexdigest()) #返回产生的十六进制的bytes
print(hash.digest()) 
 
 
######## sha1 ########
 
hash = hashlib.sha1()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
# ######## sha256 ########
 
hash = hashlib.sha256()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
 
# ######## sha384 ########
 
hash = hashlib.sha384()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
# ######## sha512 ########
 
hash = hashlib.sha512()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 1 Hash objects have these methods:
 2  - update(arg): Update the hash object with the bytes in arg. Repeated calls
 3                 are equivalent to a single call with the concatenation of all
 4                 the arguments.
 5  - digest():    Return the digest of the bytes passed to the update() method
 6                 so far.
 7  - hexdigest(): Like digest() except the digest is returned as a unicode
 8                 object of double length, containing only hexadecimal digits.
 9  - copy():      Return a copy (clone) of the hash object. This can be used to
10                 efficiently compute the digests of strings that share a common
11                 initial substring.
官方说明

5、添加添加自定义key再来做加密

import hashlib
 
# ######## md5 ########
 
hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
hash.update(bytes('admin',encoding="utf-8"))
print(hash.hexdigest())

6、直接使用hmac

import hmac
 
h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
h.update(bytes('admin',encoding="utf-8"))
print(h.hexdigest())

7、自定义密码加密模块

 1 #!/usr/bin/env python
 2 # -*- coding: utf8 -*-
 3 # __Author: "Skiler Hao"
 4 # date: 2017/4/9 15:26
 5 import hashlib
 6 from hashlib import sha256
 7 import random
 8 import hmac
 9 
10 
11 def _create_salt():
12     salt = sha256(str(random.random()).encode('utf-8')).hexdigest()[-8:]
13     return salt
14 
15 
16 def set_password(password,salt = None):
17     if not salt:
18         salt = _create_salt()
19     hashed_pwd = hmac.new(bytes(salt, encoding=("utf-8")))
20     hashed_pwd.update(bytes(password, encoding=("utf-8")))
21     return hashed_pwd.hexdigest()+'$'+salt
22 
23 
24 def check_pwd(pwd, hashed_pwd_salt):
25     hashed_pwd,salt = hashed_pwd_salt.split('$')
26     new_hash_pwd_salt = set_password(pwd,salt)
27     if new_hash_pwd_salt == hashed_pwd_salt:
28         return True
29     else:
30         return False
mypassword

8、对Web的api添加认证,增加安全性:

客户端:基于SECRET_KEY和时间,进行md5加密,生成动态的auth_key

1 # 用于API认证的KEY,直接在settings配置,注意安全,不要随意泄露给它人
2 KEY = '299095cc-1330-11e5-b06a-a45e60bec08b'
settings
 1     def auth_key(self):
 2         """
 3         用于生成auth_key,对key进行封装
 4         :return: 将加密后的动态key以字典形式返回
 5         """
 6         key = hashlib.md5(self.key.encode('utf-8'))  # 将key作为盐先放进去,增加复杂度
 7         auth_time = time.time()  # 获取当前时间,混入其中
 8         key.update(bytes("%s|%f" % (key, auth_time), encoding='utf-8'))
 9         encryption_key = key.hexdigest()
10         result = "%s|%f" % (encryption_key, auth_time)
11         # 可以将key放入request的headers部分,由于键不能为下划线,建议使用-
12         return {'auth-key': result}
客户端的加密过程

服务器端: 

 验证步骤:

    1、验证时间是否过期,设置为5s,或者在settings里面配置

1 ASSET_AUTH_KEY = '299095cc-1330-11e5-b06a-a45e60bec08b'
2 ASSET_AUTH_HEADER_NAME = 'HTTP_AUTH_KEY'
3 ASSET_AUTH_TIME = 2  # 默认时间为秒
settings

    2、收到的auth_key进行解密验证

    3、3s内访问过的加入list禁止再次访问

def api_auth_validation(request):

    # 从请求的header部分拿到encryption_key
    encryption_key_timestamp = request.META.get('HTTP_AUTH_KEY')
    # 拿不到则直接报错
    if not encryption_key_timestamp:
        return False

    sp = encryption_key_timestamp.split('|')
    # 检查加密后的key,和时间是否用|隔开样式是否正确
    if len(sp) != 2:
        return False
    # 拿到加密后的key和request时间
    encryption_key,request_time = sp
    request_time = float(request_time)

    current_server_time = time.time()
    # 时间失效,或者请求的时间戳是未来的,都报错
    if current_server_time - ASSET_AUTH_EXPIRE_TIME > request_time | current_server_time < request_time:
        return False

    # 拿到服务器存储的key进行加密验证
    ha = hashlib.md5(ASSET_AUTH_KEY.encode('utf-8'))
    ha.update(bytes("%s|%f")%(ASSET_AUTH_KEY,request_time))
    result = ha.hexdigest()
    # 如果不等的话直接返回False
    if result != encryption_key:
        return False
    exist = False
    del_keys = []
    # 拿到ENCRYPT_LIST,判断是否访问过
    for k,v in enumerate(ENCRYPT_LIST):
        print(k,v)
        m = v['time']
        n = v['encrypt']
        
        if m < current_server_time - ASSET_AUTH_EXPIRE_TIME:
            # 如果超时加入要删除的列表,做好删除准备
            del_keys.append(k)
            continue
        if n == encryption_key:
            # 是否有存在的内容
            exist = True
    for k in del_keys:
        del ENCRYPT_LIST[k]
    if exist:
        return False
    # 验证完全通过加入到ENCRYPT_LIST
    ENCRYPT_LIST.append({'encrypt':encryption_key,'time':request_time})
    # 最后再返回True
    return True
具体方法

 

 

 

如有转载,请标明出处,如有任何建议,请留言

posted @ 2017-04-09 15:56  skiler  阅读(4864)  评论(0编辑  收藏  举报