Hallo Word

zhizheng & blog

密码学的学习笔记

密码技术手段:数据指纹,身份证明,消息的可信度和不可抵赖性,数据加密 信息安全(机密性,完整性,可用性,不可抵赖性) Hash函数 hash可以用于校验文件是否完整,数字签名的摘要信息等等 hash函数是将任意大小的输入映射成固定大小的哈希值的函数 hash函数具备抗原像性(无法通过哈希值求到输入的值,是具备单相性的),抗次原像性(很难得到两个不同输入内容确得到相同的hash值),雪崩效应(原文的改变会导致hash值发生变化),抗碰撞性(很难得到可以生成相同hash值的输入内容) 常见的哈希函数:md4,md5,sha1,sha224,SM3(国密发布),sha256,sha384,sha512等等 md5发布于于1992年,摘要长度为128个比特,hash值为16位字节(128/8=16),块大小512个比特(每一次计算都以512个比特来分组处理),轮计算4(16 step)(一共进行4轮的计算,每一轮计算16步,一共计算64步) 简单的来说就是hash值长度是16位字节,计算过程中每个512比特的数据块都会进行64步的计算 sha1发布于1995年,摘要长度为160个比特,块大小512个比特,轮计算4(20 step) md5和sha1的计算过程: 先将原消息作为一个头部,然后填充一个64位的尾部(这个尾部是说明了原消息有多长),然后中间填充一个经过计算得到的多少个位的数据(确保头部和尾部大小,以及中间的大小的和是512的倍数,这个中间会在开头填1,然后填0,直到头部和中间,以及尾部的bit是512的倍数为止),这个目的是将任意大小的原信息计算切成多个512的块,计算完成后是没有余的 也就是输入信息长度除于512不等于512-64时,进行填充,填充1和n个0,让其总长度等于(512-64)+512的倍数,这个填充是必须进行的,即便输入信息长度等于512-64,也要进行填充一个512bit的数据,确保填充位数是1到512之间 确保这个消息的长度=输入消息+64+填充 = 512的整倍数 md5会初始化4个32bit的值,sha1会初始化5个32bit的值 md5将512的块数据进行分组,分成16个32bit的子分组,然后对4个初始值进行循环计算 每个512块数据都需要进行4轮处理,每一轮64步的计算,然后得到128的结果,这个128位的结果将作为下一组的初始值,一直计算到最后的一组,得到就是128位md5哈希值 计算过程:在1到16步计算时,顺序获得16个子分组进行计算(即第几步就获取第几个分组的数据,例如第3步计算,使用第3组子分组进行计算),在17步到32步计算时,将跳跃获取16个子分组进行计算(跳跃的长度取决于当前的步数+5,即第18步时,获取2+5,第7组的数据),在33步到48步计算时获取当前步数+3,在49步到64步计算时获取当前步数+7,计算完成时,得到的数就是md5哈希值 如果有多个区块的数据,计算的步数就是n*64了,只是初始值变成了上一个区块计算完成的结果 mod 模计算 sha1原理和md5差不多,只是变成了80个步。并且将在20,40,60,80步用不同的计算方式 注意:md5和sha1都不安全了 md5 cryptographically broken and unsuitable for further use users should avoid using the MD5 algorithm in any capacity. As previous research has demonstrated, it should be considered cryptographically broken and unsuitable for further use sha1 谷歌SHA1碰撞实验 结论:应该放弃md5,sha1,改用sha2,sha3,BLAKE2等更安全的哈希函数 对称加密 AES,发布于1997年,其是迭代类型的加密,分组长度128bit,密钥长度有128,192,256,轮数分别10,12,14 计算过程: AES加密计算会进行4种操作,轮密钥加(AddRoundKey),字节替代(SubBytes),行移位(ShiftRows),列混淆(MixColumns) 128位的明文和128位的密钥被分组成16个子节,变成4*4的正方形矩阵 加解密的每一轮的密钥都是通过密钥扩展算法得到的,因此轮密钥也是4*4的正方形矩阵...

2024-03-01 · 2 min · Me

云计算学习笔记

云服务平台:微软的Azure,开源云服务平台Open Stack,谷歌家的Google Cloud,亚马逊的AWS,国内的阿里云,京东云,华为云,腾讯云等等公有云,私有云 云计算就是通过互联网按需访问计算资源,例如物理服务器和虚拟服务器资源,数据存储器等等,这些资源都由云服务提供商管理,云服务提供商通过这些资源,并且根据使用情况按量收费 云计算的特点:按需使用,按量收费,弹性资源,自助服务(即开即用,无需审核),无人值守(高可用,无需监守) 亚马逊在2006年推出S3和EC2,2008年谷歌发布Google App Engine,2009年heroku发布Paas,2010年微软推出Azure服务平台,2011年Open Stack发布开源Iaas,2014年亚马逊推出lambda(无服务器计算服务) 云计算类似于水电服务,电力部门已经为你架构好了基础设施,无需再投资建设基础设施 云计算按需支付按需使用,无需再使用服务器来浪费用不到的资源,多用资源,使用时间长更省钱 云计算保证业务高可用,运维自动化,资源自动扩缩,无需人为管理 云主机,云服务器,云端服务器 创建云主机,指定规格 核心数量,内存,磁盘,网络(私有地址,公有地址),操作系统,操作系统账户(密码,ssh密钥),地理位置,防火墙(安全组) openstack 构建私有云或者公有云 安装openstack OpenStack 是一个基于Python的开源项目,安装太复杂了,将通过kolla-ansible快速部署OpenStack环境 kolla-ansible使用ansible自动化运维工具进行OpenStack服务编排部署,kolla-ansible采用可全容器部署,全部跑在docker容器中 OpenStack官方要求8g内存,40g磁盘 Kolla Ansible支持Ubuntu20.04,Ubuntu22.04,Debian 11系统,支持Ubuntu,centos,Debian容器 Kolla Ansible官方文档地址:https://docs.openstack.org/kolla-ansible/yoga/user/quickstart.html 这里将使用Ubuntu22.04 安装必要依赖 sudo apt install git python3-dev libffi-dev gcc libssl-dev sudo apt install python3-pip pypi换源(适合国内朋友) pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 安装 ansible(官方要求ansible版本大于4,小于6) sudo apt install ansible 或者 sudo pip install -U ‘ansible>=4,<6’ 安装Kolla-ansible sudo pip install git+https://opendev.org/openstack/kolla-ansible@master 创建目录 sudo mkdir -p /etc/kolla 复制kolla-ansible配置文件(例如globals.yml和passwords.yml,清单文件)...

2024-02-27 · 2 min · Me

C++学习笔记

C++的历史最早追溯到1979年,Bjarne Stroustrup创建了带类的C(即C的超集),这就是C++的雏形,直到1983年,才正式成为C++ C++标准委员会在1998年发布了第一个国际标准C++ ISO/IEC 1488,又叫C++ 98 2011年,C++ 11标准发布,boost库诞生,11标准之后,c++每3年发布一个版本,每一个版本保持向后兼任性的同时,还提供新功能以及改进 C++的特点:封装能力强,高性能,低功耗(可在微型设备上运行,例如嵌入式设备) C++主要用于开发桌面应用程序,后台系统引擎,游戏以及游戏引擎,图像视觉和AI引擎,数据库(例如MongoDB),嵌入式开发 C++是编译型语言,C++程序会经过编译器生成中间的目标程序,再通过链接器,将目标程序和程序库链接到一起,最后生成可执行程序 .cpp程序经过编译器生成汇编程序.asm,再通过汇编器生成目标程序.obj,链接器会将目标程序和其他目标程序以及一些库程序链接到一起,生成可执行文件 Windows下直接安装Visual Studio,选择使用C++的桌面开发和通用Windows平台开发,Visual Studio扩展插件选上 如果需要开发移动设备的开发,也可以选择使用C++的移动开发选项,还有使用C++的Linux开发,根据自己需求选择 第一个C++程序 #include<iostream> int main() { std::cout << "hallo word!\n"; } 运行以及调试程序:生成,生成解决方案,清理解决方案,编译 C++的每一个变量是具备其数据类型的,该数据类型决定了该变量在内存的空间大小以及该内存空间的值范围,该变量能参与哪些运算,例如: int sum; // 定义整形 int a = 1; int b = 1; sum = a + b; // 求和 一些常见的类型的定义: #include "stdafx.h" void main(void) { char a[6]="qq"; short int a = 88; long int a = 99; int a = 99; float a = 3....

2024-02-17 · 2 min · Me

汇编基础学习笔记

x86架构通用寄存器(32位的x86架构和64位的x86_64架构) x86_64架构由amd公司推出,因此又叫amd64架构,64位架构是基于32位架构扩展的 32位架构的x86处理器具备8个32位的通用寄存器,可通过名称来引用这8个寄存器,分别为EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI EAX的低16位可以被单独使用,引用名称叫AX(高位是左边位,低位是右边位),AX又可以被分为高8位的AH和低8位的AL 实质上EAX,ECX,EDX,EBX都可以被拆开使用,ECX的低16位叫CX,CX又可以被分为高8位的CH和低8位的CL EDC的低16位叫DX,DX又可以被分为高8位的DH和低8位的DL,EBX的低16为叫BX,BX又可以被分为高8位的BH和低8位的BL ESP,EBP,ESI,EDI的低16位也可以被单独使用,但是没有8位的,这低16位名称分别是SP,BP,SI,DI EAX寄存器被乘法和除法指令自动调用,因此又叫累加寄存器 ECX被LOOP(循环)指令调用为循环计数器 ESP被用于寻址栈上的数据,ESP始终指向栈顶,因此又叫栈指针寄存器 ESI和EDI又叫变址寄存器,变址寄存器引用的是内存地址,ESI指向内存源地址,EDI指向目的地址 EBP叫帧指针寄存器,被用来引用栈上的函数参数和局部变量 除了通用寄存器还有EFLAGS标志寄存器,EIP指针寄存器(这个非常重要,因为其引用的是下一条要被指向的指令的地址,注意:并不能直接通过名称来说调用,只能通过CALL之类的间接修改)等等 64位架构(通用寄存器为16个,并且是64位的,而且每个都可以低8位,16位,32位单独使用) EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI的64位是R开头的,其他和32位架构是一样的,64位架构的内存地址也是64位的 x86汇编指令(通常是由一个操作码(opcode)和0到多个的操作数(operand)组成) 整数加减指令(ADD指令(有2个操作数,分别是目的操作数和源操作数,ADD指向将这2个操作数的值相加,将结果存放在源操作数中,源操作数可以是寄存器,内存,目的操作数要满足可写条件,因此也可以是寄存器,内存,但是不能同为内存))和SUB指令(和ADD指令一样,但是是将结果存放在目的操作数中)) ADD指令:ADD EAX,32 (将EAX寄存器的值加上32,并且将结果存放回EAX寄存器中) SUB指令:SUB ESP,32 (将ESP寄存器的值减去32,并且将值存放回EAX寄存器中) 数据传输指令(x86架构有多个数据传输指令,这里是MOV指令) MOV指令用于寄存器之间和寄存器和内存之间传输数据使用,MOV指令将源操作数复制到目的操作数中,例如MOV EDX, 666 (将数值666存储在EDX寄存器中) x86架构内存寻址:displacement(位移,可以在指令中直接得到内存的偏移量,也就是位移,这个位移表示距离操作数的直接偏移量),base(基址,内存地址存储在通用寄存器中),index(索引,注意ESP寄存器不能用于索引),scale(比例因子,用于索引相乘,是固定值,可取值1,2,4,8) 内存最复杂的地址计算公式:base+(index*scale)+displacement base和index,displacement都可以随意组合,也可以不存在,如果不使用index,就不需要使用scale了,scale只为index服务,index和scale被用于寻找数组地址和多维数组 入栈和出栈指令(PUSH和POP指令) PUSH指令只有一个操作数,就是需要入栈的源操作数,这个指令可以将ESP寄存器向下移动一个位,并且将源操作数复制到ESP寄存器指向的内存处,例如:PUSH EAX POP指令也是只有一个操作数,就是用来接收数据的目的操作数,POP指向会将ESP寄存器指向的内存处的值复制到目的操作数中,并且将ESP寄存器向上移动一个位置,例如:POP EAX 分支跳转指令(JMP指令) JMP指令只有一个操作数,这个操作数可以是内存,寄存器或者立即数,通过这个操作数来给出需要跳转的目的地址,例如 JMP EAX 过程调用指令(CALL指令) 高级语言的函数在汇编叫过程,CALL指令只有一个操作数,是过程的起始地址,例如 CALL EAX 分支跳转指令和过程调用指令的区别是,分支跳转指令不会记录返回地址,这个返回地址是CALL指令之后的下一条指令的地址,CALL指令会将返回地址入栈,然后跳转到目的地址执行 子过程执行完成通过RET指令返回,RET指令会在栈上弹出返回地址,并且跳转到该返回地址上继续执行 内存分页机制 线性地址 在内存分页模式中,应用使用的地址就叫线性地址,由MMU(menorymanagement unit)基于页表来映射转换为物理地址 在内存分页模式未出现之前,应用是直接访问物理内存的,应用具备读写全部物理内存的权限,因此可能会覆盖其他应用的数据,而80386架构出现,出现了保护模式,使用内存分页来通过特权级和进程地址空间来进行隔离 进程地址空间隔离是通过进程独立性页表来完成的,每个进程实现的地址空间是不同的,避免影响到其他进程 80386两级页表 80386架构的线性地址为32位,因此可寻4GB大小的内存空间(4096),地址总线也是32位,因此也是只能寻找4gb大小的物理内存,而且分页机制也将每个物理内存的页面的大小设为4096字节 一个页面大小为4096字节,地址总线为32位,因此一个页面可存储1024个物理页面地址,80386页表的第一页面是目录页面,物理内存地址存储在CR3寄存器中,可通过该目录页面来查找第二页面的1024个物理页面地址 MMU将32位的线性地址,低12位是页内偏移,然后的低10位是页表的索引,最后的高10位是页面目录索引,页内偏移的取值范围为0到4095,页表索引和页面目录索引的取值范围为0到1023 80386线性地址转换到物理地址的过程:先从CR3寄存器中获取页目录的物理地址,然后选择一个页表,在到页表索引中,找到页面的物理地址,最后通过页内偏移量来得到实质上的物理地址 PAE三级页表 80386架构的每个进程可使用4gb的线性地址空间,但是操作系统会将4gb的地址空间划分成用户空间和内核空间,为了解决内存空间不够使用,英特尔公司推出了物理地址扩展技术(PAE,PhysicalAddressExtension) PAE将地址总线扩展到36位,因此可寻找64gb的物理内存,但是线性地址依然是32位的,为了解决32位线性地址支持36位的物理地址映射,MMU页表映射机制进行了调整,一个页面只能存储512个地址 PAE的32位线性地址是,高2位是页目录指针索引,后面9位是页目录索引,再后9位是页表索引,最后12位是页内偏移 x64四级页表 因为PAE技术并没有扩展线性空间,32位的地址宽度不够使用了,AMD公司基于x86架构扩展而出的x64架构,x64架构的寄存器宽度是64位的,但是线性地址只使用了48位,但是也足够了,因为可以寻高达256TB的内存空间地址,具体可寻多少物理内存空间,取决于地址总线的宽度 x64架构,在PAE的基础上扩展了页表为4级,而且每个页面的大小是4096字节,高9位是页目录指针表,后9位是页目录指针,再后9位是页目录,然后9位是页表。最后12位是页内偏移量 虚拟内存 进程是以内存页面为单位向操作系统申请内存的,现代操作系统中会对申请的内存空间进行记录,并不会马上分配,而是等到该进程真正访问该内存空间是才会分配物理页面并且进行映射,然后恢复中断程序,如果进程访问了没有映射的内存空间,会被操作系统进行page fault处理,操作系统通过page failt handle进行检查内存空间分配记录 物理空间不够分配时,操作系统可以将少使用的物理页面写入到磁盘交换分区(Swap分区)中,将空出来的页面给需要的进程使用,注意:当在磁盘交换分区中内存页面被访问了,也会触发page fault处理,操作系统通过page failt handle来将磁盘交换分区的内存页面加载回内存中...

2022-11-20 · 1 min · Me

Deno js运行时环境学习笔记

Deno是基于V8引擎,使用Rust构建的JavaScript & TypeScript 运行时环境,天生支持TypeScript,并且有安全模式(默认情况下无法获取网络,文件系统,环境变量等权限,当然也可以开放),Deno的作者是Nodejs之父Ryan Dahl,构建的原因是解决Nodejs的缺陷,例如模块的安全性(Node运行时的权限很高,缺乏模块的安全运行),Deno的模块化选择了ESMoule标准,而且具备浏览器的api,例如window全局变量,支持onload,onunload等事件函数,支持fetch,Web Workers等标准,异步操作返回采用Promise,支持await Deno不使用node_modules与package.json的包管理机制,而是采用下载编译的机制,并且存在缓存,模块更新通过更新缓存来完成 Deno有个特殊的功能,就是可以从网络上导入模块 安装 Linux curl -fsSL https://deno.land/install.sh | sh 或者 windows iwr https://deno.land/install.ps1 -useb | iex 也可以通过scoop安装 scoop install deno 作为Rust构建的,当然也支持Cargo包管理器安装 cargo install deno –locked 或者通过单一的可执行文件来安装(我采用这个方式,再配置一下Path环境变量就是可以了,windows选择deno-x86_64-pc-windows-msvc) https://github.com/denoland/deno/releases 检查是否安装完成 deno –version 第一个例子 import DFetch from "https://deno.land/x/dfetch/mod.ts" DFetch.get("https://zhizheng123.test.com").then((response) => { console.log(response) }) 运行 deno run .\index.ts 它会向你询问进行网络请求,是否允许,可通过–allow-net默认运行,例如:deno run –allow-net .\index.ts 第三方库通过https://deno.land/x查找 权限 –allow-env,允许访问环境变量,可指定环境变量列表,通过逗号分隔 –allow-hrtime,允许高分辨率时间测量 –allow-net,允许网络访问,可指定网络地址列表,通过逗号分隔 –allow-ffi,允许加载动态库,动态库不是安全运行的 –allow-read,允许读取,可指定读取文件列表或者目录,使用逗号分隔 –allow-run,允许运行子进程,这个子进程不是安全运行的,可指定子进程列表,通过逗号分隔 –allow-write,允许写入,可指定写入文件列表或者目录,使用逗号分隔 -A 或者 –allow-all 允许全部权限 VsCode插件deno deno内置工具 安装模块...

2022-11-11 · 1 min · Me