zoukankan      html  css  js  c++  java
  • 为什么还要记密码?

    前言

    良好的习惯是人生产生复利的有力助手。

    2020年第八篇文章,继续今年的flag:每周至少更新一篇文章。

    今天的问题来源于内部的一次分享,关于密码的存储问题。

    在互联网时代,大家每天接触的app和网站太多了,注册账户大部分的场景都需要密码。

    密码的生成和存储成为了大家日常生活中常见的事情。

    很多朋友面对这样的情况,一部分朋友的选择是设置和记忆最多三个以内的密码,太多实在记不住。有时候密码还设置的非常弱,比如常见的弱口令 123456,123123等等。另一部分的朋友,则会把每个网站或者app的密码都分别存到本地,或者同步到云(网盘或者文档),用的时候去搜索和复制。

    这样的密码生成和存储方式,从安全和易用角度来说都有一定的问题。

    一.密码生成与存储安全

    1. 多应用相似/相同密码

    密码制度本身因安全需求而生,但是由于密码的生成和存储麻烦,用户为了省事使用同一套密码,带来了“撞库”这类的风险。各种数据和案例也已经证明,“撞库”攻击早已日夜相伴于我们的身边,已极具规模化和专业化。

    “撞库”按中文的字面意思解读,就是“碰撞数据库”的意思,“数据库”中往往存储着大量敏感数据,比如我们登录一个网站所需要的用户名、密码,再比如手机号、身份证号等个人隐私信息。撞库的主要场景是通过已有的账号密码列表,通过登陆正常应用的形式,试图获取正确的账号/密码组合,大白话就是“盗号”。值得注意的是,盗号并不是撞库攻击的唯一目的,验证某个账号有没有在一个站点中注册过也是常见的撞库目的。

    撞库离我们远吗?实际情况如何?事实证明这类例子并不少见。

    • 携程因出现技术漏洞,导致个人信息、银行卡cw安全码等信息泄漏
    • 小米被爆用户资料泄漏,涉及800万小米论坛注册用户信息
    • 多家快递公司被爆网站存在漏洞遭入侵,有1400万条个人信息被泄漏
    • 智联招聘86万用户简历泄漏
    • 东方航空大量用户订单泄漏
    • 12306火车订票网站被人撞库

    随着近年来物联网设备的爆炸性增长,导致人们对数据流量的可见性普遍缺乏,从而大大增加了整体威胁面和公司的漏洞。数据泄露事件不断增加,导致撞库攻击成为近年来常用的一种入侵办法。

    2. 密码的存储

    密码的存储方式,在前言的说明中,有朋友则会把每个网站或者app的密码都分别存到本地,或者同步到云(网盘或者文档),用的时候去搜索和复制,这样也是有问题的。

    • 本地存储的时候,没办法多平台同步,在家或者工作地方都用密码的时候就会很麻烦,易用性较差。

    • 云上同步,比如很多网盘和在线文档工具,都可以用来存储密码,也可以多平台同步,但是无论哪个厂商也无法保证自己的数据永远不会泄露,而且每次使用密码,都需要打开存储密码的应用搜索查找 感觉很麻烦。

    二.用户侧的解决方案

    思路

    解决密码生成的安全问题,主要是为了防止撞库,最好的办法当然是不同的网站用不同的密码,而且网站密码强度要很高,比如密码中必须要有数字和大小写字母

    当然这么多密码怎么记?这就涉及密码的存储问题,我个人的建议是不要存储,每次都自动生成,这样就不用记忆密码,也不用担心泄露了。参考 https://github.com/ls0f/pwm 开源项目,给大家提供一下思路:

    用户只需要记一个salt,也就是密码生成中的“加盐”策略,不同网站的密码按照(salt+domain+account)的拼接生成sha1,其中domain为域名,account为账户名,然后取sha1的前面15位生成密码,然后再固定规则转换大小写和数字,满足网站的强密码要求。

    这种方式,只要你的salt安全,你的密码就会安全。

    show code

    下面给大家提供Python 和js 的实现方式,大家可以把页面 部署到自己的VPS或者github Page里,这样就可以随意生成密码了。

    Python:

        def gen_passwd( raw):
    
            if sys.version_info > (3, 0):
                h = hmac.new(self.key.encode(), raw.encode(), sha1)
                base64 = b64encode(h.digest()).decode()
            else:
                h = hmac.new(self.key, raw, sha1)
                base64 = h.digest().encode("base64")
            _passwd = base64[0: self.passwd_length]
            return _format_passwd(_passwd)
    
        def _format_passwd(passwd):
            # 格式化密码,必须包含大小写和数字
            self.num_str = "0123456789"
            self.low_letters = "abcdefghijklmnopqrstuvwxyz"
            self.upper_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            passwd = passwd.replace("+", '0')
            passwd = passwd.replace("/", '1')
            list_passwd = list(passwd)
    
            if re.search(r"[0-9]", passwd) is None:
                list_passwd[-3] = self.num_str[ord(passwd[-3]) % len(self.num_str)]
    
            if re.search(r"[a-z]", passwd) is None:
                list_passwd[-2] = self.low_letters[ord(passwd[-2]) % len(
                    self.low_letters)]
    
            if re.search(r"[A-Z]", passwd) is None:
                list_passwd[-1] = self.upper_letters[ord(passwd[-1]) % len(
                    self.upper_letters)]
    
            return ''.join(list_passwd)
    
        gen_passwd("salt+domain+account")
    
    

    javascript:

            function gen_passwd(key, raw){
                var shaObj = new jsSHA("SHA-1", "TEXT");
                shaObj.setHMACKey(key, "TEXT");
                shaObj.update(raw);
                var hmac = shaObj.getHMAC("B64");
                console.log(hmac);
                var passwd = hmac.substring(0, 15);
                console.log(passwd);
                passwd = passwd.replace("+", '0');
                passwd = passwd.replace("/", '1');
                console.log(passwd);
                passwd="abcdefg123789123";
                var list_passwd = passwd.split('');
                if (!RegExp("[0-9]").test(passwd)){
                	console.log("[0-9]",passwd[13]);
                    list_passwd[13] = "0123456789"[passwd[13].charCodeAt(0) % 10]
                    console.log("[0-9]",list_passwd[13]);
                };
                if (!RegExp("[a-z]").test(passwd)){
                	console.log("[a-z]",passwd[14]);
                    list_passwd[14] = "abcdefghijklmnopqrstuvwxyz"[passwd[14].charCodeAt(0) % 26]
                     console.log("[a-z]",list_passwd[14]);
                };
                if (!RegExp("[A-Z]").test(passwd)){
                	console.log("[A-Z]",passwd[15]);
                    list_passwd[15] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[passwd[15].charCodeAt(0) % 26]
                     console.log("[A-Z]",list_passwd[15]);
                };
                // charCodeAt
                var final_passwd = list_passwd.join('');
                console.log(final_passwd);
                return final_passwd;
            }
    

    在部署的页面上试一下,再也不用每次去记忆,搜索密码了。

    三.厂商侧的解决方案

    一句话,不用传统的账号密码登陆体系,手机登陆,二维码登陆都挺好。

    最后

    关注公众号:七夜安全博客

    回复【1】:领取 Python数据分析 教程大礼包
    回复【2】:领取 Python Flask 全套教程
    回复【3】:领取 某学院 机器学习 教程
    回复【4】:领取 爬虫 教程
    回复【5】:领取 编译原理 教程
    回复【6】:领取 渗透测试 教程
    回复【7】:领取 人工智能数学基础 教程

    本文章属于原创作品,欢迎大家转载分享,禁止修改文章的内容。尊重原创,转载请注明来自:七夜的故事 http://www.cnblogs.com/qiyeboy/

  • 相关阅读:
    vue中倒计时的用法
    ant.design 中各种问题
    vue-cli3.0跨域代理问题
    vue-cli3.0配置多页面应用
    vue-axios中post和get携带参数和token
    后台返回的时间戳转化为前端的日期
    微信与支付宝二维码在页面中的使用
    git梗概介绍
    键盘和鼠标事件的区别和使用
    vue.js学习笔记(5)— Vue路由传参
  • 原文地址:https://www.cnblogs.com/qiyeboy/p/12640640.html
Copyright © 2011-2022 走看看