• 通用密钥,无需密码,在无密码元年实现Passkeys通用密钥登录(基于Django4.2/Python3.10)


    毋庸讳言,密码是极其伟大的发明,但拜病毒和黑客所赐,一旦密码泄露,我们就得绞尽脑汁再想另外一个密码,但记忆力并不是一个靠谱的东西,一旦遗忘密码,也会造成严重的后果,2023年业界巨头Google已经率先支持了Passkeys登录方式,只须在设备上利用PIN码解锁、指纹或面部辨识等生物识别方式,即可验证身份,也就是说,可以和密码说拜拜了。

    什么是PassKeys

    Passkeys的原理很简单,就是在用户注册环节,可以选择生成一对密钥,分别是公钥和私钥,公钥存在服务器端,而私钥存在用户需要登录的设备上,包含但不限于电脑、手机、或者平板。

    只有在公钥和私钥配对,并且验签通过的情况下,系统才会判定用户登录成功,也就是说,就算黑客进入到了服务器,窃取到了用户的公钥,仍然无法伪造用户的身份。

    另一方面,当我们在客户端登录账户的时候,可以选择安全性相对较高的PIN码解锁、指纹或面部辨识等生物识别方式解锁私钥,如此,就算设备不慎遗失,也可以确保私钥的安全性,不会被恶意使用。

    以Google账户为例子,只需要登入Google的账号首页:

    account.google.com
    

    随后在右侧菜单选择安全性-》通行密钥,随后创建通行密钥即可,以后如果想登录Google账号的时候,直接使用通行密钥进行生物识别登录即可,当然,前提是当前设备需要支持指纹识别或者面部识别等功能,实在不行,也可以用pin码登录,比使用冗长的密码要方便多了。

    如果需要通过多台设备进行登录,则可以在对应设备上创建不同的通行密钥,如此在任意设备登录账号都不需要输入密码了,需要注意的是,如果想把设备出售,可以在服务端直接删除公钥,这样设备中的私钥也会失效,确保账户的安全。

    总的来说,Passkeys就是一种基于非对称加密算法的登录验证方式,只不过私钥和生物识别技术连结了起来,比传统私钥更加的安全,关于非对称加密算法,请移步:加密,各种加密,耙梳加密算法(Encryption)种类以及开发场景中的运用(Python3.10),这里不再赘述。

    基于Django4.2实现

    Google账户的Passkeys支持是极好的,那么如果我们想在自己的平台接入Passkeys功能, 该如何做呢?这里以基于Python3.10的Web框架Django4.2为例子进行演示。

    首先安装Django4.2

    pip3 install Django==4.2
    

    接着安装相关的其他依赖:

    cffi==1.15.1  
    cryptography==38.0.1  
    Django==4.2  
    django-sslserver  
    fido2==1.1.1  
    pycparser==2.21  
    pytz==2022.5  
    sqlparse==0.4.3  
    django-passkeys
    

    可以放入requirements.txt进行批量安装。

    随后在终端通过命令创建Django命令:

    django-admin startproject test_app
    

    需要注意的是,由于触发生物识别的接口只支持https协议,所以需要django-sslserver启动基于Https协议的后台服务,确保配置文件中已经进行配置:

    # Application definition  
      
    INSTALLED_APPS = [  
        'django.contrib.admin',  
        'django.contrib.auth',  
        'django.contrib.contenttypes',  
        'django.contrib.sessions',  
        'django.contrib.messages',  
        'django.contrib.staticfiles',  
        'test_app',  
        'passkeys',  
        'sslserver'  
    ]
    

    随后,配置一下数据库:

    DATABASES = {  
        'default': {  
            'ENGINE': 'django.db.backends.sqlite3',  
            'NAME': 'test_db',  
        }  
    }
    

    这里我们就使用默认的简易数据库sqlite3,当然换成Mysql也可以,原理都是一样的,数据库用来存储用户生成的公钥,存在服务端。

    至此Django4.2就配置好了。

    使用Openssl配置证书

    想要启动基于Https协议的Django服务,需要单独配置SSL的证书,这里使用Openssl,下载地址是:

    https://slproweb.com/products/Win32OpenSSL.html
    

    下载后进行安装,别忘了配置环境变量,随后第一步,生成服务器私钥:

    openssl genrsa -out server.key 2048
    

    第二步,根据私钥和输入的信息生成证书请求文件:

    openssl req -new -key server.key -out server.csr
    

    第三步:用第一步的私钥和第二步的请求文件生成证书:

    openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650
    

    这样我们就拿到了私钥server.key和证书server.crt。

    在生产环境中,这些步骤对用户来说是不可见的,这里只是简单模拟,通常证书申请用户只需要将服务器的公钥(注意不是私钥)和服务器证书申请文件交给https证书厂商即可,之后https厂商会通过邮件回复一个服务器公钥证书,拿到这个证书和自己生成的服务器私钥就可以搭建https应用了。

    需要注意的是,私钥长度必须大于1024,否则启动时会报密钥过短的错误,同时密钥如果过短,也会增加被破解的风险。

    随后用证书启动Django服务:

    python3 manage.py runsslserver --cert D:/Downloads/server.crt --key D:/Downloads/server.key  0.0.0.0:8000
    

    程序返回:

    Watching for file changes with StatReloader  
    Validating models...  
      
    System check identified some issues:  
      
    WARNINGS:  
    passkeys.UserPasskey: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.  
            HINT: Configure the DEFAULT_AUTO_FIELD setting or the AppConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.  
      
    System check identified 1 issue (0 silenced).  
    June 21, 2023 - 12:22:55  
    Django version 4.2, using settings 'test_app.settings'  
    Starting development server at https://0.0.0.0:8000/  
    Using SSL certificate: D:/Downloads/server.crt  
    Using SSL key: D:/Downloads/server.key  
    Quit the server with CTRL-BREAK.
    

    则代表没有问题,至此证书就配置好了。

    使用Passkeys

    现在,我们可以使用Passkeys功能了,首先迁移数据库:

    python3 manage.py migrate
    

    注意这一步并不需要model的支持,因为django-passkeys三方库会自动创建。

    随后为Django-admin后台创建一个超级管理员:

    python3 manage.py createsuperuser
    

    程序返回:

    System check identified some issues:  
      
    WARNINGS:  
    passkeys.UserPasskey: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.  
            HINT: Configure the DEFAULT_AUTO_FIELD setting or the AppConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.  
    Username (leave blank to use 'zcxey'): admin  
    Email address: admin@123.net  
    Password:  
    Password (again):  
    The password is too similar to the username.  
    This password is too short. It must contain at least 8 characters.  
    This password is too common.  
    Bypass password validation and create user anyway? [y/N]: y  
    Superuser created successfully.
    

    这里创建了一个admin账号。

    随后访问地址:https://localhost:8000 ,注意,必须是https协议。

    随后在passkeys管理页面中创建私钥:

    由于笔者的电脑不支持生物识别,所以只能用pin码。

    创建成功后,私钥会留在设备中,也就是客户端,通过生物识别来解锁。

    而公钥则存在Django项目的Sqllite3数据库中,随时可以对用户的私钥进行验签操作。

    下次登录的时候,只需要用私钥登录即可,把密码丢到九霄云外去吧:

    结语

    虽然这只是非对称加密算法的一次简单地落地实践,但却是用户登录体验的一次革命性的巨大提升,还在给1password软件付费?这笔开支可以省了,最后奉上Passkeys示例项目,与众乡亲同飨:

    https://github.com/zcxey2911/Django4.2_Passkeys_Login_Demo
    
  • 相关阅读:
    多肽细胞穿膜肽TAT修饰牛血清白蛋白BSA/人血清白蛋白HSA/卵清白蛋白OVA纳米粒(实验要求)
    一文带你了解 Spring Security 集成 Authing OIDC 认证
    Springboot中的多环境开发
    管理类联考——数学——汇总篇——知识点突破——代数——等差数列——最值
    软件测试/测试开发丨Selenium Web自动化测试 高级控件交互方法
    mysql 客户端SSL错误2026 (HY000)
    代码 - 多张图片合并成PDF(每页宽高即是当前页面图片的宽高)- itextpdf
    如何保证PCB孔铜高可靠?
    双十一蓝牙耳机推荐哪款?发烧友推荐目前最值得入手的蓝牙耳机
    设计模式 (原则)
  • 原文地址:https://www.cnblogs.com/v3ucn/p/17495992.html