家里有熊孩子看我输入密码怎么办?

密码安全

今天(2024年9月9日)是2024年的国家网络安全周的日子了,借着这个机会,我们来探讨一下,你使用的密码真的安全吗?

很多人可能对此感到疑惑:密码安全?我的密码为什么会不安全呢?

实际上,在现代的安全领域,认证通常基于三种原则,也被称为是认证的三要素:

你本身的特征(something you are):也就是生物识别特征,包括常见的指纹,人脸等。

你拥有的东西(something you have):这种认证方式是你持有的东西,比如说u盾,安全令牌,包括现在最常用的手机验证码短信。

你知道的东西(something you know):这是最常见的认证方式,也就是应该只有本人知道的信息,例如密码,安全问题,都属于这个类别。

这样一看,密码真的安全吗?实际上并不,因为密码属于你知道的东西,如果你知道的东西被别人也知道了,不就不安全了吗?下面,我们就具体探讨一下,密码可能会如何受到威胁,如何才能更加安全呢?


存储密码的安全性

存储明文密码

在一个软件,或者网站登录的时候,我们需要输入密码。众所周知,如果要输入密码,就要先存储密码,那么,软件的制作者,网站的运营者就必须要保存用户的密码,那么该如何保存呢?

首先我们需要明确一件事情:明文存储是绝对不可以的,这是非常危险的行为!一旦密码泄露,用户的密码,就会被直接泄露和被人利用。

下面,我们演示一下密码的存储和登录,注意,在真实的环境中,密码通常会存储到数据库中,但为了简化程序,着重于演示原理,我们现在就不使用数据库。

password_dict = dict()

def register(username, password):
    if username not in password_dict:
        password_dict[username] = password  # 注意,这种明文存储密码的方式,是不安全的,不可以使用
        return "注册成功"
    else:
        return "重复的用户名"
    
def login(username, password):
    stored_password = password_dict.get(username)
    if stored_password and stored_password == password:
        return "登录成功"
    else:
        return "用户名或密码错误"

在这里插入图片描述
如果像这样直接存储了密码,那么密码泄露就会造成很大的危害。


存储哈希密码

使用哈希算法来加密密码,并且存储,就可以大大提高安全性,虽然这不是最好的,但是比存储明文要好得多。

import hashlib

password_dict = dict()

def hash_password(password):
    # 使用sha256的哈希算法来加密密码
    pwdhash = hashlib.sha256(password.encode("utf-8")).hexdigest()
    return pwdhash

def register(username, password):
    if username not in password_dict:
        password_dict[username] = hash_password(password)
        return "注册成功"
    else:
        return "重复的用户名"
    
def login(username, password):
    stored_password = password_dict.get(username)
    # 在登录时,我们需要对提供的密码进行哈希处理,然后再与存储的密码的哈希值进行比较
    if stored_password and stored_password == hash_password(password):
        return "登录成功"
    else:
        return "用户名或密码错误"

在这里插入图片描述
以密码123456为例(注意:弱密码123456同样也是不应该被使用的),现在存储的值变成了:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

这个值非常复杂,不再能够简单的知道原始密码是多少,大大增加了安全性。但是需要注意的是,由于123456是一个弱密码,它的sha256的哈希值早就被记录下来了,因此,虽然不能直接看出是多少,但是去密码记录中查一下,就可以轻松的反推出,原始密码是123456。


存储哈希加盐密码

盐可以帮助增加密码的复杂度,简单来说,为每个密码,生成一个随机的盐,然后在加密的时候,通过盐和密码的组合,得到的组合结果,进行哈希加密,此时,即使是简单的密码,它的结果也会变得非常复杂,难以被反推和破解。

更重要是,由于每个密码的盐都是不一样的,因此,即使是相同的密码,他们得到的结果也是不一样的,这有效的防止攻击者通过一个密码的破解,就掌握了所有的相同密码。

import hashlib
import os

password_dict = dict()

def hash_password(password):
    
    # 为密码生成一个随机的盐值
    salt = os.urandom(32)
    
    # 使用盐值和密码的组合,进行哈希
    pwdhash = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, 100000)
    
    # 存储盐值和哈希值,注意,在实际使用中,分开存储是更常见的
    # 但是在我们的字典实现中,将其合并存储会更方便一些
    return salt + pwdhash

def register(username, password):
    if username not in password_dict:
        password_dict[username] = hash_password(password)
        return "注册成功"
    else:
        return "重复的用户名"
    
def verify_password(stored_password, provided_password):
    
    # 从存储的密码中提取出盐值
    salt = stored_password[:32]
    stored_hash = stored_password[32:]
    
    # 对用户提供的密码,使用对应的盐值进行哈希
    pwdhash = hashlib.pbkdf2_hmac("sha256", provided_password.encode("utf-8"), salt, 100000)
    return pwdhash == stored_hash

def login(username, password):
    stored_password = password_dict.get(username)
    if stored_password and verify_password(stored_password, password):
        return "登录成功"
    else:
        return "用户名或密码错误"

此时,我们的密码已经变得非常复杂了,在这里插入图片描述
即使是123456这样的弱密码,加密后的结果,也可能变得非常难以理解,在密码记录网站中也不可以直接查到了。但是由于弱密码仍然可以被爆破,因此无论存储多么安全,实际使用中仍然不安全。


密码泄露是否能登录

对于良好的实现来说,即使用户的密码被泄露,用户的账户也无法被登录,因为,只知道加密后的密码并不意味着可以登录账户,在输入密码时必须要输入加密之前的密码。

def login(username, password):
    stored_password = password_dict.get(username)
    
    # 在这个步骤中,我们会对输入的密码进行hash_password,因此必须提供原文
    # 如果本身密码不是弱密码,且实现良好的话,由于密文无法被反推,因此即使知道了加密后的密码
    # 也无法提供出这一步骤中所需要的原文,因此无法登录账户
    if stored_password and stored_password == hash_password(password):
        return "登录成功"

使用密码的安全性

弱密码不安全

弱密码是指,位数少,内容简单的,非常常用的密码,比如说123456asdqwe240909 等,这样的密码存在很大的安全隐患。

首先,弱密码的存储一旦被泄露,加密的哈希值很容易被反推出来。
例如,即使将123456使用sha256加密成了8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92的形式,也依然可以直接查到它的对应值。
这意味着,一旦密码存储被泄露,那么攻击者就可以得到密码原文。

其次,即使存储是安全的,攻击者仍然可以通过“弱口令爆破“等方式,来攻击和侵入你的账户,例如,循环遍历常用密码字典,然后尝试进行登录。

import requests

username = "yourusername"
url = "https://example.com"

for i in range(100000, 999999):
    data = {
        "username": username,
        "password": str(i)
    }
    try:
        r = requests.post(url, data=data)
        if r.status_code == 200:
            print(f"成功登录,密码为:{i}")
            break
    except requests.exceptions.RequestException as e:
        print(f"请求失败:{e}")
        continue

在这种情况下,只要攻击者发出了足够多的爆破请求,且你的密码足够简单,那么最终都会被他找到。

禁止使用弱密码

由于弱密码存在诸多危害,因此,在注册的时候,我们就应当禁止用户输入弱密码,这涉及到弱密码的规则定义,和检测等。

规则定义:密码应该包括的长度,是否有数字,字母大小写,特殊字符,甚至不允许与用户名相似,连续重复等。

使用简单有效的条件判断进行弱密码的检测:

def is_strong_password(password):
    
    # 检查密码长度
    if len(password) < 8:
        return False
    
    # 检查是否包含至少一个数字
    if not any(char.isdigit() for char in password):
        return False
    
    # 检查是否包含至少一个大写字母
    if not any(char.isupper() for char in password):
        return False
    
    # 检查是否包含至少一个小写字母
    if not any(char.islower() for char in password):
        return False
    
    # 检查是否包含至少一个特殊字符
    special_characters = "!@#$%^&*()-_=+[]{}|;:',.<>/?"
    if not any(char in special_characters for char in password):
        return False
    return True

或者使用方便快捷的正则表达式进行弱密码的检测:

import re

def is_strong_password(password):
    pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()\-_=+\[\]{}|;:\'",.<>?/]).{8,}$'   
    return bool(re.match(pattern, password))

多站点用相同密码不安全

很多人为了方便,经常只有一个密码,所有的站点都用这一个密码,无论在哪里注册登录,都使用相同的密码。在这种情况下,是非常危险的。

首先,可能会遭遇钓鱼网站的问题,钓鱼网站会伪装成正常的网站,或者它本身就是一个“正常”的网站但是在偷偷窃取用户的信息,这个时候,你在这个网站的注册信息和密码,都会被它拿来利用。

其次,即使是正规的网站,也会存在因为安全漏洞等导致用户密码泄露的问题,这样,该站点的密码很可能会暴露。如果你所有的站点都用相同密码,那么会遭遇“撞库”的问题。

撞库是指攻击者利用从一个或多个来源泄露的用户名和密码尝试登录其他服务,这种攻击建立在一个假设之上:许多用户会在不同的网站上重复使用相同的登录凭证,因此,攻击者会使用泄露的账户密码,大规模尝试登录各种在线账户,希望找到那些使用相同密码的账户。

所以说,这启示我们,不同的站点一定要使用不同的密码,不应该使用相同的密码。

在早期,一些程序可能会使用“键盘钩子”的技术,来提示用户不应该在其他地方使用或输入本程序的账号密码,这是通过监视用户的键盘输入做到的,这种功能虽然可以在一定程度上预防撞库,但是由于可能被视为侵犯用户隐私,通常是不合适的。

小心键盘记录器

键盘记录器,也就是keylogger,可以监测用户的一切输入,自然也可以窃取敏感信息,以及账户和密码。键盘记录器通常是某些来源不明的,不受信任的程序所导致的。

因此,为了避免键盘记录器,要尽可能不安装和使用来源不明的代码,以及程序。

另外,在互联网早期技术中,可能会告诉我们,通过“拆分输入”的方式,可以防范键盘记录器,例如,先输入密码后边的部分,然后通过鼠标光标移动到前边,再输入密码的其他部分,从而实现打乱密码顺序,防范键盘记录器。

这种技术在现如今已经被认为不再可靠,是“小聪明”,他只能应对早期简单的按顺序的键盘记录器,但是现代的功能强大的,复杂的键盘记录器比这个要厉害的多,它不仅可以记录下你所有的输入,对于你如何移动了光标,如何打乱了顺序,也都会记录的清清楚楚,甚至还会配合屏幕截图等功能,来进行记录,因此,“拆分输入”不总是有效的,而且实践中可能也没多少人愿意这样做,因为大多数情况下,可能是”在和空气斗智斗勇“。

小心监控摄像头

监控摄像头在当前是非常普遍的,到处都有监控摄像头,而且现在的监控摄像头是非常高清的,可以准确的拍下来你的一切行动。

因此,即使没有任何的“内部侵害”(你使用的不是弱密码,非常安全,且设备也没有被入侵,很安全,一切都很好),但是如果你在监控摄像头下,输入了密码,那么你输入密码的内容和顺序,都会被记录下来。如果这些监控是有人在查看的,那么他们就会得知你的密码。

这特别常见于你在商店输入了支付宝密码,或者你在单位摄像头下,输入了个人账户的密码。

现实中遇到的其他困难

上次聚会,我在输入密码的时候,亲戚家的小孩就站在我的旁边看着我输入。这个时候,我遇到了一个很大的麻烦,我是否应该让他退后呢?

如果我不出声制止,任由他站在那里,可能会泄露我的密码,对我的账户造成危害。况且,在别人输入密码的时候站在那里是一个不好的行为,这非常没有礼貌,我应该教育和指导我亲戚的小孩,不要这样做。

但是,如果我出声制止,要求他远离这里,可能会被认为我对他“不信任”,“没有把他当成亲密的亲戚”,同时,孩子的父母可能也会非常的尴尬,认为我在小题大作,没事找茬,让他们和孩子很“没有面子”,这可能会发生矛盾冲突,即使表面上他们不好发作,但是背后可能会骂我。
在这里插入图片描述

纵使在技术领域,有各种方法,可以保障安全,实行最佳规范,但是遇到了“人情问题”,就变得难以抉择和不知所措了。所以说,好兄弟们,你们认为遇到了这种情况,到底怎么做比较好呢?是应该让亲戚的小孩退后,不要看输入密码,还是应该选择忍气吞声,就当什么都不知道,任由他在这里站着呢?在评论区告诉我吧!

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞎老弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值