哈希长度拓展攻击
哈希长度拓展攻击1.什么是MAC?MAC就是Message AuthenticationCodes,即消息验证码 🔐 MAC的核心作用 认证性(Authenticity):确保消息的发送者是声称的人,即消息确实是由合法的发送者生成。 完整性(Integrity):验证消息在传输过程中是否被篡改或损坏。为了实现这些功能,发送者使用一个秘密密钥和MAC算法生成一个认证标签(MAC值),这个标签随消息一起发送。接收者也拥有同样的密钥,可以用相同算法重新生成MAC值。如果重新计算的值和收到的值一致,就可以确认消息没有被改动。 这个标签也叫做tag MAC系统包含以下三个算法 A keygeneration algorithm selects a key from the key space uniformly atrandom. A MAC generation algorithm efficiently returns a tag given the keyand the message. A verifying algorithm efficiently verifies th...
reverse常见函数
逆向积累1.字符串相等这里i64相当于LL 0i64=0LL,1i64=1LL 12345678910111213141516__int64 __fastcall equal(_QWORD *a1, _QWORD *a2){ __int64 v2; // rbx int v4; // ebx unsigned __int64 i; // [rsp+28h] [rbp-58h] v2 = sub_425120(a1); if ( v2 != sub_425120(a2) ) return 0i64; for ( i = 0i64; sub_425120(a1) > i; ++i ) { v4 = *(_DWORD *)sub_425200(a1, i); if ( v4 != *(_DWORD *)sub_425200(a2, i) ) return 0i64; } return 1i64; 1234__int64 __fastcall sub_425120(_QWORD *a1){ return (__int64)(a1[1...
reverse_note
1.什么是PE?PE( Portable Execute)文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS 等。它是微软在 UNIX 平台的COFF(通用对象文件格式)基础上制作而成。最初设计用来提高程序在不同操作系统上的移植性,但实际上这种文件格式仅用在Windows 系列操作系统下。PE文件是指 32位可执行文件,也称为PE32。64位的可执行文件称为 PE+ 或PE32+,是PE(PE32)的一种扩展形式(请注意不是PE64) 总而言之就是可执行文件 一个文件是不是可执行文件和后缀名无关 在Linux中,ELF是可执行文件 image-20250627223959874## PE文件的结构包括DOS头,NT头,节表以及 具体的节** dos头的作用 兼容性: 当PE文件在DOS系统下运行时,DOS头中的代码会执行,通常显示一个错误信息(例如:”This program cannot be run in DOS mode.”)。在现代Windows系统中,操作系统会跳过DOS部分,直接解析PE头。 标识PE文件: DOS头的起始两个字节是魔...
Coppersmith归纳
归纳一下Coppersmith 1.Background我们可以利用LLL算法来求解模多项式问题 比如我们想要求解这个模多项式方程,这个是困难的,我们可以考虑构造整数上与之同解的方程,使得 我们知道当f(x)的系数比较小的时候,这个模多项式方程有可能变成多项式方程,这就可以考虑使用LLL算法求得约化基 注意到 而且同解,沿着这个思路也是同解的,然后我们把h进行线性组合,寄希望与他们的系数可以相互抵消,使得系数绝对值变小 先考虑 引理Howgrave-Graham设h(x)是一个有d个单项式的多项式,如果满足 那么,可以在整数集上求解 由 根据柯西不等式 而 那么 所以 根据上面这个,我们来构造 这个模数没统一,我们不妨固定为m吧,那这样的话,前面构造就得改 于是有 构造 只需令 那怎么找到这样的g呢 我们用的系数向量造格子 寻找满足的向量 不妨令LLL约化得到的b_1为这个向量,那么 只需令 未完待续,但其实根据前面这个引理,已经能得到很多东西了
递归和迭代的区别
递归和迭代有什么区别? 递归的实质是将问题拆解成一些好处理的子问题,而迭代则是一步一步解决问题 一、递归如何思考?当我们使用递归的时候,应该思考三件事 1.怎么把大的问题分解成可以处理的小问题 2.拆解到什么程度? 3.怎么归?(临界条件?) 二、迭代如何思考?迭代的时候,我们应该想的是,根据现有的,我应该怎么做? 以前序遍历为例子 如果使用迭代来做,我应该想的是 前序遍历需要访问根结点,左子树,右子树,当我访问根结点的左子树的时候,根节点这个信息丢失了,导致我没办法再找到右子树 所以我们应当时刻记录根节点,也就是一个顺序表 那么这个顺序表有什么特征呢,最上层的根节点,最先进来,但是只有我们把他的左子树那边全部遍历完,才轮到它的右子树,所以他是最后进来的,所以这就是一个栈结构,先进后出 而栈顶恰恰是当前访问节点的根节点 创建一个栈,先左行,记录根节点, 然后直到左子树为空,这时候访问此时栈顶的右结点, 那此时这个栈顶元素是否利用完了?没错,因为保留这个栈顶元素就是为了访问右子树,所以可以出栈了 那么到这个右子树之后呢,还是要左行,然后和上面是一样的 什么时候结束呢,当这个栈为空的...
二叉树
二叉树1.二叉树的抽象类型12345678struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; 一个二叉树结点包含值,左子树和右子树 2.二叉树的层序遍历给你二叉树的根节点 root ,返回其节点值的层序遍历 。 (即逐层地,从左到右访问所有节点)。 每次访问一层,访问完一层后,从最左边的结点的左子树开始访问,所以先进先出 考虑用一个队列 先让根结点进来,然后我们取出根节点,先让根节点左子树进队列,然后再让右子树进队列,然后再取队头,此时又是根结点的左子树,保持了从左到右的顺序...
外排序
外排序由于内存有限,我们需要把外存的数据分成好几段,然后把这些段数据分别排序 这些已排序的段称为顺串 假设有m个顺串,每次对k个顺串进行归并 那么需要归并次,为了提高效率,一个是降低顺串的个数,另一个就是增加归并的k 1.置换选择排序假设我们有超过内存的数据要进行排序,假设内存为c,那么每次得到长度为c的初始顺串那么,有没有办法增加顺串的长度呢,可ff以考虑用堆来实现假设我们要求从小到大排序,那么维护一个长度为c的最小堆,可以得到多长的顺序串呢?每次取堆顶的时候,如果堆顶元素大于已经在输出缓存区的元素,那么就可以取,否则我们就不应该取,这样会破坏已经有序的输出缓存区,那么这时候,我们就只能取堆中剩下的元素,我们把不能取的那个元素丢到最后,然后继续维护堆,这时候堆的长度为c-1,直到有c个都不能取的元素由于取每个元素大于输出缓存区的元素的概率是1/2,那么这个顺串的期望长度是2c这样就扩大了读取的顺串长度,平均扩大了两倍 用到的堆 1234567891011121314151617181920212223242526272829303132333435363738394041424...
苦读密码学引论--hash
HASH函数hash函数就是将映射到的函数,即将任意长度的比特串映射为n-bits 即 其中H叫做像,M是原像 一个好的hash函数需要满足一下属性 1.抗原像攻击给定H,找到X,使得h(X)=H是困难的 2.抗第二原像攻击(弱抗碰撞)给定X,找到X’使得h(X)=h(X’)是困难的 3.抗碰撞攻击找到任意两个X和X’,满足h(X)=h(X’)是困难的 (任何一个第二原像都不存在) 为什么抗碰撞性更强? 如果一个哈希函数是抗碰撞的,那么它必然也是抗第二原像的。 理由: 如果攻击者能对一个给定的 x成功进行第二原像攻击(找到 x’ 使得H(x’) = H(x)),那么他实际上就找到了一个碰撞对(x, x’)。所以,抗碰撞失败必然导致抗第二原像失败。 反之则不然!一个哈希函数可以是抗第二原像的,但却不抗碰撞。 理由: 攻击者可能无法为某个特定的、随机的x 找到碰撞伙伴x’(满足抗第二原像),但他可能通过精心构造的方法找到任意一对特殊的消息y 和 y’(y 和 y’都不是那个特定的 x),使得H(y) = H(y’)(即不抗碰撞)。MD5就是一个经典例子:虽然在实际中寻找第二原...
H&NCTF2025-crypto
H&NCTF1.lcgp常规的LCG问题, 观察函数generate 123def generate(self): self.seed = (self.a * self.seed + self.b) % self.m # %代表取余运算 return self.seed 输入seed,获得一个新的seed 接着循环了5次,产生了5次种子 换而言之,我们需要利用这5个种子,求出一开始的种子 不妨设,一开始的seed为x1,然后我们写成数列的形式 已知求 接着来看算法的关键这里面a,b,m都是未知的,b好处理,因为在常数的位置,两个式子相减就能消掉 考虑 这时候,我们以作为一个新数列,那么这时候只剩下两个未知数了 设 那么 于是构造了一个等比数列说到等比数列,等比中项就是一个有趣的性质,那么,对于这个同余的等比数列,是否有着等比中项呢,可以一试 a消失了,那么此时,只剩下m这一个未知数 把同余式写成等式 可以求出k1m,k2m,等等 如果两个k没有公因数的话,那么m就是它们的最大公因数 1234567891011from Crypto.U...
H&NCTF2025
H&NCTF2025 CryptoCryptolcgp常规的LCG问题, 观察函数generate 123def generate(self): self.seed = (self.a * self.seed + self.b) % self.m # %代表取余运算 return self.seed 输入seed,获得一个新的seed 接着循环了5次,产生了5次种子 换而言之,我们需要利用这5个种子,求出一开始的种子 不妨设,一开始的seed为x1,然后我们写成数列的形式 已知求 接着来看算法的关键 这里面a,b,m都是未知的,b好处理,因为在常数的位置,两个式子相减就能消掉 考虑 这时候,我们以作为一个新数列,那么这时候只剩下两个未知数了 设 那么 于是构造了一个等比数列 说到等比数列,等比中项就是一个有趣的性质,那么,对于这个同余的等比数列,是否有着等比中项呢,可以一试 a消失了,那么此时,只剩下m这一个未知数 把同余式写成等式 可以求出k1m,k2m,等等 如果两个k没有公因数的话,那么m就是它们的最大公因数 1234567891...