Python标准库之加密模块详解
作者:微小冷
通过random生成随机码
一般来说,若想生成一段随机字符串密码,可通过random来实现,具体方法如下
import random import string TOTAL = string.ascii_letters + string.digits + string.punctuation def genSecrets(L=16): return "".join([random.sample(TOTAL, 1)[0] for _ in range(L)])
其中TOTAL即从string模块中挑选出的所有字母、数字以及标点符号,作为密码的字符集,然后通过random.sample从TATOL中抽取特定长度的字符,最终得到一个字符串,效果如下
>>> genSecrets()
'~5~sn6fWH\\W^`L6W'
>>> genSecrets(20)
':rWOGXY{jus{.?D/&MaY'
>>> genSecrets(128)
'e~qzAB],FkU82"0N<yX)M0l>OIsWfA\\G$?K?*ANg"ii\\e~YQ?3QQ9dToZ_\\IzhDuS8(]V!o_Wzkz}sI?pJS&fAs|i|;P}-T*-OtY9G=`27|2\\<6-]/.q:|ODV"j#X5s]'
但众所周知,伪随机数模块random生成的随机数并不随机,其原理无非是按照当前时间进行编码,然后从随机数表中索引到一个值。换言之,genSecrets这个函数生成的密码并不安全。
secrets
相比之下,secrets模块可用于生成高度加密的随机数,这些随机数适合做密码。
secrets中主要有三个函数,分别用于生成随机字节字符串、十六进制文本字符串以及URL随机字符串,其使用方法如下,输入参数为字符串长度。
>>> from secrets import * >>> token_bytes(16) b't\x98\x00\x86\xfa:\xdeV(E\xb0\x82\x96\x80T\xb3' >>> token_hex(16) '1b65dcaf5f1e9bd96fa8639b966d7cde' >>> token_urlsafe(16) '8EgjGpnKISzTM2WgPYk4tQ'
当然,除了这三个主要函数之外,secrets也具备基本的随机数功能,即
- choice(lst) 从lst中挑选出一个元素返回
- randbelow(n) 生成小于n的自然数
- randbits(n) 生成不超过n位bit的随机整数
>>> choice([1,2,3]) 1 >>> randbelow(5) 3 >>> randbits(5) 10
Python标准库中提供了一些secrets的使用技巧,例如生成长度为八个字符的字母数字密码:
import string import secrets alphabet = string.ascii_letters + '0123456789' password = ''.join(secrets.choice(alphabet) for i in range(8))
XKCD风格密码
所谓XKCD,尽管带有CXK三个字,但经过严密地考证,发现和ikun没什么关系,而且也不是某些单词的缩写,这四个字母仿佛是随机选出来的。而之所以选择这四个字母,乃因这四个字母连在一起没法组成任何音节,就是发不了音。
简单来说,XKCD其实就是用单词来取代字符作为密码的最基本元素,由于单词都是有含义的,所以由单词组成的密码,相对来说是比较好记的;但另一方面,单词所蕴含的字节数是远多于字符的,换言之,用单词组成的密码,不易被破解。
如下面代码所示,通过四个单词组成了一个密码
import secrets words = ["单词","蕴含","字节","字符","密码", "简单", "发音"] pw = " ".join(secrets.choice(words) for _ in range(4)) print(pw) # '字节 密码 密码 蕴含'
当然,一般来说这个词库是比较大的,从词库中挑出一组对自己来说有意义而对别人来说没啥意义的词汇,也是比较容易的。仅就上面的字节密码密码蕴含来说,至少包含32个字节,想暴力破解几乎是不可能的,想要记忆却很容易,想要推测却也十分困难。
到此这篇关于Python标准库之加密模块详解的文章就介绍到这了,更多相关Python加密模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!