基于机器学习的密码强度检测

  • A+
所属分类:安全文章

基于机器学习的密码强度检测


原文:Machine Learning based Password Strength Classification

地址:http://web.archive.org/web/20170606022743/http://fsecurify.com/machine-learning-based-password-strength-checking/

近期,我想做一些机遇机器学习和网络安全的项目。这是另一个与信息安全和机器学习有关的项目。

各公司的密码强度检测都不近相同。但所有的这些检测都是基于规则的。一个密码在Google这边可能是强密码但在Dropbox就变成了弱密码。我在想我们能否让机器学习算法来决定一个密码是弱密码还是强密码。于是,这个帖子诞生了。让我们开始吧。

数据收集

此次分析所使用的密码数据来自于000webhost泄漏,此数据可在网上下载。那么我们是如何决定哪些密码是高强度的哪些密码是低强度的呢?Well,Georgia Tech university开发了一款名叫PARS的工具,这款工具集成了各大公司所使用的密码强度检测规则。这些文件有两行数据,密码和强度。

我在此使用的密码强度检测算法来自于Twitter,微软和暴雪。这个算法与其他检测仪有什么区别呢?首先,它是纯粹基于机器学习而不是密码规则的。其次,我只保留了那些三种检测仪都认为强度是弱、中等、强的密码。这意味着所有用来训练的密码的强度都确实是弱、中等、强的。

下面是一些用来训练模型的密码样本:

0 for weak, 1 for medium and 2 for strong
lamborghin1,1
AVYq1lDE4MgAZfNt,2
u6c8vhow,1
v1118714,1
universe2908,1
as326159,1
asv5o9yu,1
intel1,0
612035180tok,1
jytifok873,1
WUt9IZzE0OQ7PkNE,2
lsdlsd1,0

我原本有300万条密码数据,但是过滤出满足三个密码强度检测仪后只剩下70万条密码数据了,我将这些数据分为了80%的训练集和20%的测试集。其中过滤掉了许多数据是因为我只用了那些被三个分类算法都认为是相同强度的密码。

数据分析

我将使用Tf-idf分数而不是整条密码,我将使用每个字符作为一个token。其他我没用到的指标有密码长度,特殊字符的数量,包含数字的数量等。这是一个自定义的令牌解析器(tokenizer)。

def getTokens(inputString):
tokens = []
for i in inputString:
tokens.append(i)
return tokens

加载数据。

filepath = 'your_file_path_containing_passwords_and_labels'
data = pd.read_csv(filepath,',',error_bad_lines=False)

data = pd.DataFrame(data)
passwords = np.array(data)

现在打乱数据集,然后获取y和X向量。

random.shuffle(passwords)
y = [d[1] for d in passwords]
allpasswords= [d[0] for d in passwords]

现在在我们的密码语料库(corpus)上使用Tfidvectorizer分割数据。

vectorizer = TfidfVectorizer(tokenizer=getTokens)
X = vectorizer.fit_transform(allpasswords)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)

That's it. 现在我们需要做的就是应用机器学习算法然后我门就拥有了一个基于机器学习的密码强度检测器。开工!由于我想让算法运行更快一些,在此我使用了多分类的逻辑回归算法。

lgs = LogisticRegression(penalty='l2',multi_class='ovr')
lgs.fit(X_train, y_train)
print(lgs.score(X_test, y_test))

我们的准确率(accuracy)大概有81%,这可能是由于我们没有使用大量的数据。这代表80%的情况下,我们算法能够将密码正确分类(与三个商业的密码检测器分类结果相同)。让我们来看看这个算法是如何将我们的密码分类的。

X_predict = ['faizanahmad','faizanahmad123','faizanahmad##','ajd1348#28t**','ffffffffff','kuiqwasdi','uiquiuiiuiuiuiuiuiuiuiuiui','mynameisfaizan','mynameis123faizan#','faizan','123456','abcdef']
X_predict = vectorizer.transform(X_predict)
y_Predict = lgs.predict(X_predict)
print y_Predict

来看看结果。

faizanahmad [medium]
faizanahmad123 [medium]
faizanahmad## [medium]
ajd1348#28t** [strong]
ffffffffff [easy]
kuiqwasdi [medium]
uiquiuiiuiuiuiuiuiuiuiuiui [easy]
mynameis123faizan# [strong]
faizan [easy]
abcdef [easy]

看起来我们的算法知道字母、数字和特殊符号的组合是一个好的密码。很好,结果看起来很好,不是吗?

有一些需要注意的地方,由于此模型是从已经存在的检测算法中的规则训练的,但我组合了三种不同的检测方法来使他更可靠(robust)。它不只是基于算法模仿了一个规则。它综合了广泛使用的许多密码强度检查算法。

这个项目是我在闲暇时间做的,它肯定是不完全的。这只是实现我心中的一个想法,然后分享与你们大家。我相信这个项目可以进一步扩展为更强大,更有意义的密码检测器/分类器。

代码和数据可以在此找到:

https://github.com/faizann24/Machine-Learning-based-Password-Strength-Classification

基于机器学习的密码强度检测


本文始发于微信公众号(T00ls):基于机器学习的密码强度检测

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: