在ECC中,Pohlig-Hellman攻击可以用来降低特定情况下的离散对数问题的求解难度。
我们知道想要破解ECC最大的难题是ECDLP,即椭圆曲线离散对数问题
假设我们已经知道了椭圆曲线上的基点G和公钥Q,想要从Q=kG中求解私钥k目前没有找到比朴素算法更优的解决方案
我在学习这块内容的时候突然有了个疑惑(之前完全没意识到,好奇怪),就是为什么椭圆曲线加密使用的是Q = kG,却被称作离散对数问题?对数在哪?这不就是看起来很普通的乘法吗?
那我们就先跳出椭圆曲线,先来研究有限域乘法群
设在有限域FP∗设在\color{blue}有限域\mathbb{F}_P^{*}设在有限域FP∗,定义运算*为模p乘法,在该有限域中存在生成元g,使得h=gkmod ph=g^k\mod{p}h=gkmodp,离散对数就是已知h和g求解k的过程。这样显然k的表达式会出现对数,且由于运算进行在有限群中,所以称为离散对数
上面h=gkmod ph=g^k\mod{p}h=gkmodp,显然可以写为h=g∗g∗g+....mod ph = g*g*g+....\mod{p}h=g∗g∗g+... ...
w
蒙哥马利阶梯算法的核心是通过 “二进制分解 + 固定步骤迭代” 实现对一个 “标量”(整数)的高效计算,经常用于做点标量乘法和模幂运算
本文主要讲解蒙哥马利阶梯算法在ECC上点标量乘法的计算
蒙哥马利阶梯算法(Montgomery Ladder)
蒙哥马利阶梯算法是一种通用的算法,但它与蒙哥马利曲线结合时效率更高
要理解蒙哥马利阶梯算法如何计算点的标量乘法,我们还得把Double and Add算法拉过来打配合
我们知道Double and Add算法的基本流程
假如求5P
我们把5用二进制表示为101
根据二进制各位的权值,遍历每一位的时候都有乘法,但会有一个很重要的if语句:
12if n == 1: add_point
而在n == 0的时候显然少了一步点加操作
这就会导致我们的算法在处理0和1时,工作的时长有明显差异
而又有那么一种很不传统的密码分析方法——侧信道攻击,即通过分析时间、功耗、电磁辐射、声音甚至温度变化等物理信息来分析
这就会使得我们的密码不那么安全
而蒙哥马利算法在0和1上的步骤差异很小,能有效避免侧信道攻击
蒙哥马利算法的步骤如下:
1234561.初始化 ...
a
椭圆曲线密码学(Elliptic Curve Cryptography,ECC)
是一种基于椭圆曲线数学理论的非对称加密算法。它和我们已经学习过的RSA一样,依靠陷门函数来保证加密算法的安全性。
要学习ECC,我们先要学习一些前置知识
椭圆曲线
它并非指椭圆的边界线,而是指满足特定方程的曲线。
最基础的研究场景是复数域,在其中椭圆曲线的标准方程为:
y²=x³+ax+b(Weierstrass形式)
a和b为常数,且满足Δ=−16(4a³+27b²)≠0(非奇异条件)
曲线方程有多种形式。这里只给出了Weierstrass形式
而在实际应用中,椭圆曲线一般定义在有限域上,此时该方程在有限域内进行。
我们知道有限域内的元素是有限个,因此椭圆曲线作为一种点的集合,其中的点也是有限个。
同时,该椭圆曲线满足非奇异条件确保曲线上每个点都有唯一一条切线(后面会用到)
点加法
我们在椭圆曲线所在的有限域上定义运算“点加法”
倘若我们在椭圆曲线上寻找两个点P和Q,做直线PQ与椭圆曲线交于第三点R,然后再对R的y值取相反数,得到R’
那我们就说P+Q = R’
那么如果出现直线PQ与椭圆曲线没有第 ...
Python
未读在做Cryptohack中迪菲赫尔曼协议部分时,题目需要我们连接到某个端口,获取和发送数据
此处应有做题记录,如果没有就是我忘了放
pwntools库可以作为我们写解题脚本的一种选择
这里只展示crypto中需要用到的功能
安装和引用123pip install pwntoolsfrom pwn import *
与程序交互12345678910111213141516171819202122#本地交互p = process('') #内填本地程序路径#远程连接r = remote( , ) #左填地址,右填端口#发送数据r.send(data)r.sendline(data) #发送单行数据(末尾有换行符)#接受数据r.recv(data)r.recvline(data)r.recvuntil() #接收数据直到出现括号内分隔符r.recvregex() #接收数据直到出现与括号内重合内容r.clean() 清楚缓存数据#获取shellr.interactive() #进入交互模式#关闭连接r.close()
好用的小功能12345678#逐字节异或xor( ...
Crypto
未读我们加密、解密信息都需要利用到密钥
那么密钥信息是如何安全配送的呢?难道我们一定要俩人线下秘密会面吗?
**Diffie-Hellman密钥交换协议(Diffie-Hellman Key Exchange,DHKE)**就是一种可以通过互联网安全配送密钥的方式
它的工作方式是这样的
假设Alice和Bob之间想要确定一个密钥k
Alice和Bob先商量好一个质数p和某个有限域的生成元g,通常会选取安全质数p=2⋅q+1(q是另一个大质数)。这能保护迪菲 - 赫尔曼协议免受波赫里格 - 赫尔曼算法的攻击。
Alice生成一个秘密数字a,计算A = g^a mod p
Alice把A发给Bob
Bob生成一个秘密数字b,计算B = g^b mod p
Bob把B发给Alice
Alice计算S1 = B^a mod p
Bob计算S2 = A^b mod p
经过这样的过程,我们由幂模运算的运算性质很容易推导出S1=S2
所以就把S1和S2定为密钥k
在上面的过程中,我们不难发现除了两人的秘密数字a和b,各个值都是直接在互联网上传递的 ...
本文将持续收录我做到的RSA有关的题
先是Cryptohack教学局
Cryptohack
Monoprime
n是质数,phi = n-1,e已知,直接求d解密
1234567891011n = 171731371218065444125482536302245915415603318380280392385291836472299752747934607246477508507827284075763910264995326010251268493630501989810855418416643352631102434317900028697993224868629935657273062472544675693365930943308086634291936846505861203914449338007760990051788980485462592823446469606824421932591 e = 65537ct = 1613675503467306044514547561890289389649412803476620987987754660194633756107 ...
RSA 是一种广泛使用的非对称加密算法,在现代密码学中占据重要地位
RSA 算法基于数论中的大整数分解问题,该问题的核心是:将一个极大的合数分解为其质因数的乘积,在计算上极其困难(目前没有高效的多项式时间算法)
作为一种非对称加密算法,RSA的加密和解密分别使用公钥和私钥来进行
RSA 的密钥生成过程
选择两个不同的大质数 p 和 q。
计算 n = p×q,n 作为公钥和私钥的一部分,是一个大合数,并且每个用户使用的n都应该是独一无二且难以分解的
计算欧拉函数 φ(n) = (p-1)×(q-1)。
选择一个整数 e 作为公钥的指数,满足 1 <e < φ(n) 且 e 与 φ(n) 互质。
计算 e 在模 φ(n) 下的逆元 d,即 d 满足 (e×d) ≡ 1 mod φ(n),d 作为私钥的指数。
公钥为 (e, n),私钥为 (d, n),其中 p、q 和 φ(n) 需要保密(它们是陷门信息的核心)。
后面写了为什么私钥要这样构建
RSA 的加密与解密过程
加密:发送方用接收方的公钥 (e, n) 对明文 m(需满足 m < n)进行加密,计算密文 c ...
**比特翻转攻击(bit flipping attack)**是一种针对CBC的常见的攻击方法
因为CBC核心是通过前一个密文块与当前明文块进行异或(XOR)运算后再加密,从而引入上下文关联性
但是异或是一种线性运算,可预测性强。
因此我们可以通过更改iv或者更改部分密文片段,经由异或运算,来实现对明文的翻转
例题
Cryptohack Flipping Cookie
观察题目代码
我们可以获得iv的信息(CBC中iv的安全性至关重要)
并且可以知道,该网站并没有对信息做完整性检测,它只检查是否存在字符串’admin=True‘存在
再有就是我们能够获得的cookie中,第一个密文块对应’admin=False‘的片段
那么我们只需要通过拟造一个虚假的iv,并且让该iv和“admin=False……”的异或结果出现“admin=True……”
1234true_iv ^ t = 'admin=False……'fake_iv ^ t = 'admin=True……'得:fake_iv = 'adm ...
前情提要:Cryptohack ECB-Oracle | AiY0u的博客
我们都知道可以根据密文字节数来判断明文的长度范围
倘若明文有33字节,那么就会分为16+16+1三部分,然后对第三部分做填充
会用到pad()函数
1from Crypto.Util.Padding import pad
使用规则为
但是pad()有一个小特性
数据长度恰好是块大小的整数倍时,函数会添加一个完整的填充块。比如,数据长度为 16 字节,块大小也为 16 字节,填充后数据长度会变为 32 字节,新增的 16 个字节每个都为0x10。
所以我们在推断明文长度时一定要看好边界情况
Oracle在密码学里通常指一个能提供特定信息的黑盒系统
而ECB这一工作模式最大的不安全性来自于这一特性——相同的明文块能够产生相同的密文块
当ECB遇到了Oracle,我们就能够通过爆破,逐步的获取每一位明文的信息。具体解题步骤如下:
分析题目代码
加密程序很简单明了,将plaintext与FLAG拼接在一起,然后进行ECB加密
这里plaintext是我们自己输入的,FLAG是固定的。
从这一点至少可以分析出,我们尝试不同长度的plaintext根据ECB加密生成的密文长度,来判断flag的长度
发现输入plaintext长度为1~6字节时,加密结果为32字节
输入plaintext长度为7字节时,加密结果为48字节
由此可知:
12len(FLAG)+6 = 32len(FLAG) = 26
真的是这样吗?
翻车记录:翻车记录之pad填充 | AiY0u的博客
所以其实我们还要再减去1,真实的FLAG长度为25
我们已知了FLAG的开头为crypto{,结尾为}
那么需要爆破16个字符,直接爆破计算量是很大的
我们需要利用开头所说的ECB的安全问题,假设我们输入的plain ...