python中的hashlib加密模块
hashlib模块提供以下常量
hashlib.algorithms_available:获取可以运行在Python解释器中的哈希算法名称的集合(set类型)
hashlib.algorithms_guaranteed:获取保证在所有平台上此模块支持的哈希算法名称的集合(set类型),为hashlib.algorithms_available的子集
创建hash对象:
hashlib.new(name[,data]):其中name为加密算法的名称(str格式),data为需要加密的数据(bytes格式)
为了简化操作,该模块为常用的加密算法添加了独立的创建方法,如md5加密算法可以使用hashlib.new(‘md5‘),也可是使用hashlib.md5()
可以使用hashlib.hash_name([data])这种方法创建hash对象的加密算法有:blake2b、blake2s、md5、sha1、sha224、sha256、sha384、sha512、sha3_224、sha3_256、sha3_384、sha3_512、shake_128、shake_256
不能使用hashlib.hash_name([data])方法创建方法的加密算法有:ripemd160、md5-sha1、blake2s256、blake2b512、whirlpool、mdc2、md4等,这些算法创建hash对象只能使用new()方法创建。
blake2算法是一个在RFC7693中定义的加密散列函数,有两种类型:blake2b()针对64位平台优化,Blake2s()针对8到32位平台优化,两个加密算法拥有相同的参数:
(data=b‘‘, *, digest_size=64/32, key=b‘‘, salt=b‘‘, person=b‘‘, fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False)
data:要加密的初始数据块 digest_size:输出密文的字节大小(blake2b最大64,默认为64,blake2s最大32,默认为32) key:键值的字节大小(blake2b最大64,blake2s最大32) salt:盐值的字节大小(blake2b最大16,blake2s最大8) person:个性化字符串的字节大小(blake2b最大16,blake2s最大8) fanout:扇出(0到255,如果不受限制,则为0,顺序模式下为1)。 depth:树的最大深度(1到255,如果不受限制,则为255,顺序模式下为1)。 leaf_size:叶的最大字节长度(0到2**32-1,如果不受限制或处于顺序模式,则为0)。 node_offset:节点偏移(Blake2b为0到2**64-1,Blake2s为0到2**48-1,第一个、最左边、叶或顺序模式为0)。 node_depth:节点深度(0到255,0表示叶,或以顺序模式)。 inner_size:内部消化尺寸(Blake2b为0至64,Blake2s为0至32,顺序模式为0)。 last_node:布尔值,指示处理的节点是否是最后一个节点(对于顺序模式为false)。
blake2算法相关的常量:
blake2b.MAX_DIGEST_SIZE or blake2s.MAX_DIGEST_SIZE:最大输出密文的字节大小
blake2b.MAX_KEY_SIZE or blake2s.MAX_KEY_SIZE:最大键值的字节大小
blake2b.SALT_SIZE or blake2s.SALT_SIZE:最大盐值的字节大小
blake2b.PERSON_SIZE or blake2s.PERSON_SIZE:最大个性化字符串的字节大小
hash对象的方法:
update(data):在将要加密的字符串后面附加上data,下面四个加密操作是等效的:
1、a = hashlib.new(‘md5‘,b‘hello world‘) 2、a = hashlib.md5(b‘hello world‘) 3、a = hashlib.md5() a.updata(b‘hello world‘) 4、a = hashlib.md5() a.updata(b‘hello ‘)#结尾有个空格 a.updata(b‘world‘)
dataigest([length])和hexdigest([length]):返回update()到目前为止传递的数据的对应加密算法的加密密文。dataigest()返回二进制的加密结果(字节类型),hexdigest()返回十六二进制的加密结果(字符串类型),不指定length按每个加密算法的默认大小计算,其中算法中‘shake_128‘和‘shake_256‘没有默认大小,必须制定length值
copy():返回当前哈希对象的副本
常见算法的默认长度:
md4(32)、md5(32)、md5-sha1(72) sha1(40) sha224(56)、sha256(64)、sha384(96)、sha512(128) sha3_224(56)、sha3_256(64)、sha3_384(96)、sha3_512(128) blake2s(64)、blake2s256(64)、blake2b(128)、blake2b512(128) whirlpool(128)、mdc2(32)、ripemd160(40)
hash对象的属性:
name:此对象正在使用的哈希算法
digest_size:此次计算输出的字节数
hash.block_size:哈希算法的内部块占用多少bytes
加盐加密:
涉及身份验证的系统都需要存储用户的认证信息,常用认证方式主要为用户名和密码的方式,为了安全起见,用户输入的密码需要保存为密文形式,可采用已公开的不可逆的hash加密算法,如SHA256,SHA512,SHA3等,在实际应用中,用户设置的密码复杂度可能不够高,同时不同的用户极有可能会使用相同的密码,那么这些用户对应的密文也会相同,这样,当存储用户密码的数据库泄露后,攻击者会很容易便能找到相同密码的用户,从而也降低了破解密码的难度,因此,在对用户密码进行加密时,需要考虑对密码进行掩饰,即使是相同的密码,也应该要保存为不同的密文,即使用户输入的是弱密码,也需要考虑进行增强,从而增加密码被攻破的难度,而使用带盐的加密hash值便能满足该需求。
加密盐的实现方法
加盐加密的实现:在用户设定的密码前面或者后面附加一个额外的字符串(称之为盐,盐值salt是一个随机字符串),然后通过加密函数计算这个新的字符串的hash值作为密码密文,最后将密码密文和盐值一起保存到数据库中。
加盐的注意事项
加盐的目的是为了增加攻击者破解的难度,那么在加盐的时候要注意以下几点,否则加盐的意义也不会太大。
1)、盐值不能太短;如果盐值只有少数两三位甚至一两位的话,攻击者完全可以穷举所有可能的盐值;
2)、盐值不能固定;如果使用了固定的盐值,攻击者可以使用该值准备密码表;
3)、不要使用能提前预知的值作为盐值;
4)、每一次修改密码时要重新生成新的盐值,不要使用上次密码对应的盐值。
hashlib模块的加盐加密方法:
hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)
hash_name,password,salt分别为加密算法名称(str类型),要加密的数据(bytes类型),盐值(bytes类型)
iterations(int类型)表示要迭代计算的次数,取决于算法和计算能力,建议设置大于100000
dklen(int类型)表示计算结果的长度,如果为默认值none,则使用对应哈希算法默认的长度,如sha-512为64
该方法返回的是二进制的加密结果(字节类型),可以使用binascii模块的binascii.hexlify()方法转换为十六进制。
hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)
基于scrypt算法的加盐加密:
n是CPU/内存成本系数,r是块大小,p是并行化系数,maxmem限制内存(openssl 1.1.0默认为32mib),dklen是生成密文的长度。该方法返回的是二进制的加密结果(字节类型)