1.cloud-init介绍及源码解读(上)
2.springsecurity中解密时如何解密的源码?
3.「博客应用」使用 Flask-Login 实现用户认证
4.AES 在线加密每次结果不一样(CryptoJS)
cloud-init介绍及源码解读(上)
cloud-init介绍及源码解读(上) cloud-init的基本概念 metadata包含服务器信息,如instance id,解析display name等。源码userdata包含文件、解析脚本、源码yaml文件等,解析早晨之星公式源码用于系统配置和软件环境配置。源码datasource是解析cloud-init配置数据来源,支持AWS、源码Azure、解析OpenStack等,源码定义统一抽象类接口,解析所有实现都要遵循规范。源码 模块决定定制化工作,解析metadata决定结果。源码cloud-init配置有4个阶段:local、network、config、波动率指示源码final。cloud-init支持多种userdata类型,如自定义Python代码、MIME文件等。用户数据类型包括User-Data Script(MIME text/x-shellscript)和Cloud Config Data(MIME text/cloud-config)。 cloud-init支持多种datasource,包括NoCloud、ConfigDrive、OpenNebula等。通过Virtual-Router获取metadata和userdata信息。 cloud-init在云主机上创建目录结构以记录信息。cloud.cfg文件定义各阶段任务。 cloud-init工作原理 cloud-init通过从datasource获取metadata,执行四个阶段任务完成定制化工作。在systemd环境下,这些阶段对应的服务在启动时执行一次。 local阶段从config drive中获取配置信息写入网络接口文件。官网程序源码network阶段完成磁盘格式化、分区、挂载等。config阶段执行配置任务。final阶段系统初始化完成,运行自动化工具如puppet、salt,执行用户定义脚本。 cloud-init使用模块指定任务,metadata决定结果。set_hostname模块根据metadata设置主机名。设置用户初始密码和安装软件是典型应用。 cloud-init源码解读 cloud-init核心代码使用抽象方法实现,遵循接口规范。主要目录包括定义类和函数、网络配置、模块初始化、低位起涨源码系统发行版操作、配置文件管理、模块处理、数据源、事件报告等。 模块通过handle函数解析cloud config配置,并执行逻辑。数据源类扩展实现接口。handler处理用户数据。reporting框架记录事件信息。 cloud-init提供文件操作、日志管理、配置解析等辅助类。其他文件包括模板处理、日志格式定义、版本控制等。 cloud-init通过模块、emlog注册登录源码datasource和配置文件实现云主机元数据管理和定制化。源码结构清晰,功能全面,是云环境定制的强大工具。springsecurity中解密时如何解密的?
在Spring Security中,密码解密的过程涉及使用BCryptPasswordEncoder类。每次输出的hashPass(散列密码)虽各异,但最终的匹配结果f总是为true,表示匹配成功。探索源码后,发现hashPass中实际包含了每次加密时生成的随机盐。
BCryptPasswordEncoder在进行密码匹配时,通过调用String hashpw(String password, String salt)方法。此方法接受两个参数:目标密码(如"admin")和已加密密码(即hashPass)中的盐值。
假设一次hashPass为:$2a$$AxafsyVqKp.s9WAEYWYeIY9TKEoGLTEOSB3KUkoLtGsBKhCwe
其中,前部的随机盐(AxafsyVqKp.s9WAEYWYe)在匹配过程中会被重新提取出来。
因此,加密后的hashPass不仅包含了密码本身,还隐含了用于加密的随机盐。这使得在验证密码时,可以准确地复现加密过程,从而实现密码的匹配与解密。
「博客应用」使用 Flask-Login 实现用户认证
在 SuzyBlog 的博客应用中,我们将实现用户认证功能,使用 Flask-Login 管理用户登录和登出。首先,确保下载 SuzyBlog 的源代码,以配合本文的学习。
在前文中,虽然已经构建了博客前台,但用户登录状态的判断是基于模拟数据。接下来,我们将重点关注Admin用户的登录登出功能。
1. 安全存储用户密码
为了保护用户隐私,不能明文存储数据库中的密码。使用 werkzeug.security 提供的 generate_password_hash 函数生成散列值,通过 salt 增加随机性,即使泄露也难以逆向获取密码。Admin模型中,通过 password 特性属性和 validate_password 方法来处理这些操作。
2. 注册命令行初始化Admin
SuzyBlog 不在网页上提供注册功能,而是通过自定义命令行工具初始化Admin用户。flask init-admin 命令行允许用户输入用户名和密码,通过 click 模块的密码装饰器保护用户输入。
3. Flask-Login用户认证
在应用中,Flask-Login 被用于区分管理员(如使用admin账号登录)和普通访客。创建 LoginManager 实例,设置用户加载函数,使用current_user变量记录登录状态。用户登录后,可以在模板中轻松访问当前用户信息。
3.1 登录管理
创建login视图处理登录请求,验证用户身份。登录成功后,用户将被重定向回首页。同时,我们为模板的页脚添加了登录/登出链接,使用query参数next来记录用户来源。
3.2 登入与登出操作
login视图中,处理表单提交并验证用户信息,login_user函数用于登录,logout_user用于登出。登录后,用户ID会保存在session中,而登出则删除这些信息。
3.3 视图保护
使用@login_required装饰器保护需要登录的视图,未登录用户将被重定向至登录页面。蓝本的@before_request装饰器可以为蓝本下的所有视图提供登录保护。
至此,Flask-Login的使用帮助我们完善了用户认证流程,使得SuzyBlog的权限管理更加安全和有序。
AES 在线加密每次结果不一样(CryptoJS)
在使用AES在线加密网站时,遇到一个问题:每次加密结果虽然不同,但都以“U2FsdGVkX1”开头。首先尝试解密base编码查看内容,发现密文总是以“Salted__”开头,这意味着网站使用了加盐处理,密文内包含了盐信息。
通过查看网站代码,发现使用了CryptoJS第三方库。在npm上找到crypto-js库,深入阅读源码后得知,cipher-core.js文件中第行左右的parse函数解析出实际密文和盐值。密文以word(一个word由8个进制,即位,4字节)为单位分割成数组,ciphertextWords[0]是盐值(例如“Salt”),ciphertextWords[1]开始是ed__后跟盐值,之后的数组元素则是实际加密信息。
进一步分析源码了解到,盐值是随机生成的,无需指定,且存在一个密钥派生函数。该函数根据输入字符串生成符合要求长度的密钥,即使用户输入的密钥长度不符合要求,也能正常加密。