16.6 示例:生成常用密码

近几年各大网站的疑似撞库以及密码泄露事件屡见不鲜,从CSDN、小米到网易等,虽然互联网技术迅速发展,但是基于用户名和密码的身份认证依然还是主流。人天生有惰性,以密码为例子,人们都喜欢在不同网站使用同样的密码,一旦某个网站的密码被泄露,黑产便可以长驱直入登录其他网站(如图16-15所示)。

图16-15 密码泄露事件

人们在设置密码的时候,总是倾向于好记的密码,于是密码便和常见实物具有很强的关联性,常见的密码之间也存在一定的关联性,我们尝试让RNN学习常见的密码,摸索其中的规律,然后自动生成新密码。完整演示代码请见本书GitHub上的16-6.py。

1.数据清洗与特征化

我们使用WVS自带的密码字典作为训练集。

约定密码长度最长不超过10,逐行读取密码本中每行密码,将数据向量化,并生成对应的样本以及标记、字典:


path = "../data/wvs-pass.txt"
maxlen = 10
string_utf8 = open(path, "r").read()X, Y, char_idx = \
    string_to_semi_redundant_sequences(string_utf8, seq_maxlen=maxlen, redun_step=3)

2.训练样本

构造RNN,使用LSTM算法:


g = tflearn.input_data(shape=[None, maxlen, len(char_idx)])
g = tflearn.lstm(g, 512, return_seq=True)
g = tflearn.dropout(g, 0.5)
g = tflearn.lstm(g, 512)
g = tflearn.dropout(g, 0.5)
g = tflearn.fully_connected(g, len(char_idx), activation='softmax')
g = tflearn.regression(g, optimizer='adam', loss='categorical_crossentropy',
                       learning_rate=0.001)

实例化基于RNN的序列生成器,并使用对应的字典:


m = tflearn.SequenceGenerator(g, dictionary=char_idx,
                              seq_maxlen=maxlen,
                              clip_gradients=5.0,
                              checkpoint_path='wvs_pass')

3.验证效果

分别设置不同的新颖度Temperature来生成密码:


for i in range(40):
    seed = random_sequence_from_string(file_lines, maxlen)
    m.fit(X, Y, validation_set=0.1, batch_size=128,
          n_epoch=1, run_id='us_cities')
    print("-- TESTING...")
    print("-- Test with temperature of 1.2 --")
    print(m.generate(30, temperature=1.2, seq_seed=seed))
    print("-- Test with temperature of 1.0 --")
    print(m.generate(30, temperature=1.0, seq_seed=seed))
    print("-- Test with temperature of 0.5 --")
    print(m.generate(30, temperature=0.5, seq_seed=seed))

运行程序,学习现有城市名称,训练数据52463条,校验数据5830条:


Training samples: 52463
Validation samples: 5830

当Temperature为1.2:


y~~
3dmgamgiaoo
ag.i@o17.tc
da#eUg^ioo

Temperature为1.0:


y~~
3dmgamiag0132
290.29
w@zwe31735)bvi

Temperature为0.5:


y~~
3dmgam
e2234687
123433
wonin12384
ja