crypto题目wp

139 阅读22分钟

crypto

一眼就解密

base64的一些特征:

1.密文中会出现“=”等号。

2.有64个可见字符。

3.代码中含有0xF、0x3F、0x3等符号

MD5

一般MD5值是32位由数字“0-9”和字母“a-f”所组成的字符串,如图。如果出现这个范围以外的字符说明这可能是个错误的md5值,就没必要再拿去解密了。16位值是取的是8~24位

Url编码

url编码是一种浏览器用来打包表单输入的格式。浏览器从表单中获取所有的name和其中的值 ,将它们以name/value参数编码(移去那些不能传送的字符,将数据排行等等)作为URL的一部分或者分离地发给服务器

看我回旋踢

ROT13编码 ROT13(回转13位,rotate by 13 places,有时中间加了个连字符称作ROT-13)是一种简易的替换式密码。

ROT13被描述成“杂志字谜上下颠倒解答的Usenet点对点体”。ROT13 也是过去在古罗马开发的凯撒加密的一种变体。

特点: 套用ROT13到一段文字上仅仅只需要检查字元字母顺序并取代它在13位之后的对应字母, 有需要超过时则重新绕回26英文字母开头即可。

A换成N、B换成O、依此类推到M换成Z,然后序列反转:N换成A、O换成B、最后Z换成M

传统知识+古典密码

XZSDMFLZ

不知道为什么工具这里是下划线

摩丝

password

姓名:张三 生日:19900315

key格式为key{xxxxxxxxxx}

flag的长度为十位,猜测为姓名的缩写“zs”,加上生日“19900315”,构成flag

变异凯撒

通过上面的acsii码值对比表可以看到第一个字符向后移了5,第二个向后移了6,第三个向后移了7,以此类推,很容易想到变异凯撒即每个向后移的位数是前一个加1:

f-102 a-97 相差5 l-108 f-102 相差6 a-97 Z-90 相差7 g-103 _-95 相差8

str="afZ_r9VYfScOeO_UL^RWUc" k=5 for i in str: print(chr(ord(i)+k),end='') k+=1

Quoted-printable

Quoted-printable 编码是一种编码方法,它使用可打印的 ASCII 字符来表示各种编码格式下的字符,以便能在 7-bit 数据通路上传输 8-bit 数据。这种编码通常用于电子邮件,特别是在 MIME(多用途互联网邮件扩展)中,它扩展了电子邮件标准,使其能够支持非 ASCII 字符、二进制格式附件等多种格式的邮件消息。

编码过程

在 Quoted-printable 编码中,任何一个 8 位的字节值可以编码为三个字符:一个等号 "=" 后跟两个十六进制数字(0-9 或 A-F)表示该字节的数值。例如,ASCII 码换页符(十进制值为 12)可以表示为 "=0C",而等号 "="(十进制值为 61)必须表示为 "=3D"。除了可打印 ASCII 字符和换行符以外,所有字符都必须以这种格式表示。

可打印 ASCII 字符(十进制值范围为 33 到 126)可以直接用 ASCII 字符编码表示,但等号 "="(十进制值为 61)除外。ASCII 的水平制表符(tab)和空格符(十进制为 9 和 32),如果不出现在行尾,则可以直接用其 ASCII 字符编码表示。如果这两个字符出现在行尾,必须通过 Quoted-printable 编码表示为 "=09"(tab)或 "=20"(space)。

解码过程

Quoted-printable 解码是将编码后的文本转换回原始文本的过程。解码时,会将 "=XX" 形式的编码转换回对应的字符,其中 "XX" 是两个十六进制数字。例如,"=3D" 会被解码为 "=","=0C" 会被解码为换页符。

使用场景

Quoted-printable 编码适用于文本数据以 ASCII 字符为主的情况,因为它的编码结果具有较好的可读性。但如果输入的大部分是非 ASCII 字符,则 Quoted-printable 编码会变得不可读且效率低下。在这种情况下,Base64 编码可能是更好的选择,尽管它不是人类可读的,但对所有数据的编码成本是均匀的,适用于二进制数据和非拉丁字母语言文本

篱笆墙的影子

Rabbit

AES、DES、RC4、Rabbit、Triple DES(3DES)

这些算法都可以引入密钥,密文特征与Base64类似,明显区别是秘文里+比较多,并且经常出现/

Rabbit开头部分通常为U2FsdGVkX1

Unencode

Uuencode 是将二进制文件以文本文件方式进行编码表示、以利于基于文本传输环境中进行二进制文件的传输/交换的编码方法之一, 在邮件系统/二进制新闻组中使用频率比较高,经常用于 Attach 二进制文件。 这种编码的特征是:每一行开头用”M”标志

世上无难事

根据提示,这段语句的明文是通顺语句,其中包含 32 位的 key,而密文语句的最后一块“640I11012805M211J0XJ24MM02X1IW09”正好为 32 位,因此猜测这段语句通过移位密码进行逐位加密

再把字母换成小写就行了

法二:爆破工具

丢失的MD5

Alice与Bob

大帝的密码武器

13位加密

Windows系统密码

信息化时代的步伐

606046152623600817831216121621196386

题目说结果为中文,结合36(4x9)位的纯数字密文,猜测为中文电码解密

凯撒?替换?呵呵!

进阶版的凯撒就不按照字母顺序的加密 如:abc=dhj 所以就要经过暴力破解出每一种可能的对应加密 用quipquip

萌萌哒的八戒

对照着来

权限获得第一步

old-fashion

也是用quipquip强行爆破

还原大师

这个就是md5爆破,脚本如下

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import hashlib
​
#print hashlib.md5(s).hexdigest().upper()
k = 'TASC?O3RJMV?WDJKX?ZM'                    #要还原的明文
for i in range(26):
    temp1 = k.replace('?',str(chr(65+i)),1)
    for j in range(26):
        temp2 = temp1.replace('?',chr(65+j),1)
        for n in range(26):
            temp3 = temp2.replace('?',chr(65+n),1)
            s = hashlib.md5(temp3.encode('utf8')).hexdigest().upper()#注意大小写
            if s[:4] == 'E903':    #检查元素
                print (s)       #输出密文
​
​

异性相吸

01100001 01110011 01100001 01100100 01110011 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01100001 01110011 01100100 01110001 01110111 01100101 01110011 01110001 01100110

00000111 00011111 00000000 00000011 00001000 00000100 00010010 01010101 00000011 00010000 01010100 01011000 01001011 01011100 01011000 01001010 01010110 01010011 01000100 01010010 00000011 01000100 00000010 01011000 01000110 00000110 01010100 01000111 00000101 01010110 01000111 01010111 01000100 00010010 01011101 01001010 00010100 00011011

依据题目猜测

a = '0110000101110011011000010110010001110011011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011000010111001101100100011100010111011101100101011100110111000101100110'
b = '0000011100011111000000000000001100001000000001000001001001010101000000110001000001010100010110000100101101011100010110000100101001010110010100110100010001010010000000110100010000000010010110000100011000000110010101000100011100000101010101100100011101010111010001000001001001011101010010100001010000011011'
c = ''
​
for i in range(len(a)):
    if(a[i] == b[i]):
        c+='0'
    else:
        c+='1'
print(c)

得到

0110011001101100011000010110011101111011011001010110000100110001011000100110001100110000001110010011100000111000001110010011100100110010001100100011011100110110011000100011011101100110001110010011010101100010001101010011010001100001001101110011010000110011001101010110010100111000001110010110010101111101 转16再转字符

RSAROLL

rsa

原理

rsarsa

RSA1

m = (((mp-mq) * I) % p) * q + mq

这段代码是用来计算明文消息 m 的一部分,通常出现在基于 RSA 的解密或签名方案中,尤其是在使用中国剩余定理(CRT)优化的场景下。以下是每一部分的详细解释:

变量解释

  • mp:是指消息在模 p 下的解密结果,即 mp = c^d mod p(其中 c 是密文,d 是私钥指数,p 是一个素数)。
  • mq:是指消息在模 q 下的解密结果,即 mq = c^d mod q(同理,q 是另一个素数)。
  • I:是预先计算好的系数,用于 CRT 的合并过程,通常是指 I = q^{-1} mod p,即 q 在模 p 下的乘法逆元。
  • pq:是用于生成 RSA 密钥对的两个大素数。

公式解释

  • mp - mq:计算 mpmq 的差值。这是因为在 CRT 的应用中,消息在模 p 和模 q 下的解密结果可能会有差异,这个差值用于调整最终的明文消息。
  • (mp - mq) * I:计算这个差值乘以预先计算好的系数 I。这一步是为了利用 CRT 的原理,将模 p 和模 q 下的解合并成模 nn = p*q)下的解。乘以 I 的目的是为了消除模 p 的影响,以便进行下一步的调整。
  • (mp - mq) * I % p:计算上述结果对模 p 取余。这一步是为了将结果限制在模 p 的范围内,同时确保结果是一个正整数。
  • ( (mp - mq) * I ) % p ) * q:将上一步的结果乘以 q。这一步是为了将调整后的结果从模 p 的范围扩展到模 n 的范围。
  • + mq:最后加上 mq,也就是消息在模 q 下的解密结果。这一步是为了将之前调整的结果与模 q 下的解结合起来,最终得到完整的明文消息 m

公式的作用

这个公式的作用是利用中国剩余定理(CRT)将消息在模 p 和模 q 下的解合并成模 nn = p*q)下的解。CRT 是一种数学定理,用于将模运算的问题分解到较小的模数上进行处理,然后再合并结果。在 RSA 解密或签名过程中,使用 CRT 可以显著提高计算效率,因为它允许我们将大模数 n 的运算分解为两个较小模数 pq 的运算,这两个较小模数的运算是相对容易处理的。

通过这个公式,我们可以高效地从在模 p 和模 q 下的解 mpmq 计算出最终的明文消息 m,而无需直接处理大模数 n 的运算,从而提高了 RSA 的解密和签名速度

RSA2

这个推导过程展示了如何计算 RSA 密钥生成中的私钥参数 d,通过约束和数学变换来简化计算并提高效率。以下是详细的解释:

方程 (1)

dp = d % (p-1)
  • 该式表示 d(p-1) 取模的结果是 dp。根据模运算的性质,这意味着 d 可以表示为 dp + k1*(p-1),其中 k1 是某个整数。

方程 (2)

d = dp + k1*(p-1)
  • 这是方程 (1) 的逆向表示。它表明 d 可以表示为 dp 加上 k1 乘以 (p-1)。这种表示方法利用了模运算的周期性,即 d 在模 (p-1) 下与 dp 等价。

方程 (3)

d * e = 1 + k2*(p-1)*(q-1)
  • 这是 RSA 密码算法中的基本关系式。它表明 de 在模 phi(n)(即 (p-1)*(q-1))下互为乘法逆元。这里的 k2 是一个整数,表示在等式中为了满足同余关系所添加的倍数。

乘法逆元

  • 在乘法运算中,一个数 a 的乘法逆元是指一个数 b,使得 a×b=1。在这种情况下,ba 的乘法逆元,通常表示为 a−1。例如:

模逆元

在模运算中,模逆元是一个数 a 的逆元,使得 a×b≡1mod_m 。这意味着 _a×b 除以 m 的余数是1。这里 ba 在模 m 下的逆元,通常表示为 a−1mod_m_。例如:

并非所有数在模 m 下都有逆元。只有当 am 互质时(即它们的最大公约数是1),a 在模 m 下才有逆元。这是因为只有在这种情况下,根据贝祖定理,存在整数 xy 使得 a×x+m×y=1。此时,x 就是 a 在模 m 下的逆元。

总结

- 5 的乘法逆元是 51,因为 5×51=1。
- 32 的乘法逆元是 23,因为 32×23=1。
- 3 在模 7 下的逆元是 5,因为 3×5=15≡1mod7。
- **乘法逆元**:在普通乘法中,一个数的逆元是其倒数,使得两数相乘得到1。
- **模逆元**:在模运算中,一个数的逆元是另一个数,使得它们的乘积在模 _m_ 下余1。只有当该数与模数互质时,模逆元才存在。

将方程 (2) 代入方程 (3)

将方程 (2) 中的 d 代入方程 (3) 中,得到:

e*(dp + k1*(p-1)) = 1 + k2*(p-1)*(q-1)

这个代入过程将方程中的 ddpk1 表示,从而将问题转化为关于 dpk1 的方程。

(p-1) 取模

为了消去方程中的系数 k1k2,对方程两边同时对 (p-1) 取模:

e * dp % (p-1) = 1

这一步利用了模运算的性质,消去了方程中的 k1k2,因为这些项都是 (p-1) 的倍数,对 (p-1) 取模后结果为零。

原方程代入后的形式

我们从方程:

e×(d**p+k_1×( p−1))=1+ k_2×(p−1)×(q−1)

开始,这里的 edpk1k2pq 都是整数。

(p-1) 取模

为了消去方程中的系数 k1k2,我们对整个方程两边同时对 (p-1) 取模。也就是说,我们计算方程两边除以 (p-1) 的余数。

左边的处理

左边是 e×(d**p+k_1×( p_−1))。

根据模运算的分配律(即 (a+b)mod_m*=[(* a_mod_m )+( b_mod_m )]mod_m),我们可以将左边拆分为两部分来处理:

  • e×dp_mod( p_−1)
  • e×k_1×( p−1)mod( p_−1)

对于第二部分 e×k_1×( p−1)mod( p_−1),因为 (p-1) 是模数,所以任何 (p-1) 的倍数对 (p-1) 取模的结果都是 0。因此,这一项可以直接忽略。

所以左边对 (p-1) 取模的结果就是 e×dp_mod( p_−1)。

右边的处理

右边是 1+k_2×( p−1)×( q_−1)。

同样地,处理右边时:

  • 1mod(p−1) 就是 1,因为 1 小于 (p-1)(这里假设 (p-1) 大于 1,这在实际应用中是成立的,因为 p 是大素数)。
  • k_2×( p−1)×( q−1)mod( p_−1),这里 (p-1) 是模数,所以这一项是 (p-1) 的倍数,对 (p-1) 取模后结果为 0。

因此,右边对 (p-1) 取模的结果就是 1。

结果方程

综合左右两边对 (p-1) 取模的结果,我们得到:

e×dp_mod( p_−1)=1

这可以简化为:

e×dp≡1mod(p−1)

这意味着 e×dp 除以 (p-1) 的余数是 1。

方程变形

从这个结果出发,我们可以将方程表示为:

e×dp=1+k×(p−1)

这里,k 是某个整数。这个方程的含义是,e 乘以 dp 的结果比 1 大 (p-1) 的某个整数倍。换句话说,e \times dp 和 1 的差是 (p-1) 的倍数。

这样,我们就通过模运算的性质消去了原来的系数 k1k2,并将问题简化为寻找满足这个新方程的 dpk。这个变形过程是数论中常用的技巧,用于简化方程和减少变量数量

方程变形

从上述结果可以得到:

e * dp = 1 + k*(p-1)

这里 k 是一个新的整数系数,用于表示方程中 (p-1) 的倍数。

解出 k

k = (e * dp - 1) / (p-1)

这个方程表示 k(e * dp - 1) 除以 (p-1) 的结果。由于 dp < (p-1)(根据方程 (1) 的定义),因此 k 的值必须小于 e

约束条件和求解

  • 根据 dp < (p-1) 的条件,可以得出 k 的值必须小于 e。因为 e 在 RSA 中通常是一个较小的固定值(如 65537),这为 k 的搜索范围提供了一个明确的上限。
  • 这个推导过程的关键在于将原本较大的未知数 d 的计算,转化为在较小范围内搜索 dpk 的值。通过利用模运算的性质和对系数的约束,可以更高效地计算出 d 的值

RSA3

推导过程解释

  1. 给定条件

这里,c_1 和 _c_2 是已知的值,分别表示明文 _m 在指数 e_1 和 _e_2 下的幂模 _n 的结果。系数 s_1 和 _s_2 是整数,满足 _e_1×s_1+e_2×s_2=1,这通常通过扩展欧几里得算法求得。

- _c_1=_m**e_1mod_n_
- _c_2=_m**e_2mod_n_
- _e_1×_s_1+_e_2×_s_2=1

2. **目标是求解明文 **** ***** m ****** *:

*   由于 *m* 对模 *n* 取模的结果就是 *m* 本身(假设 *m*<*n*),所以 *m*=*m\_mod\_n*

3. 构造指数表达式

*   利用给定的条件 *e\_1×*s\_1+*e\_*s\_2=1,我们将 *m* 表示为 *m\_1mod\_n*,即:*m*=*m\_1mod\_n*
*   将指数 1 替换为 *e\_1×*s\_1+*e\_*s\_2:*m*=*m\*\*e\_1×*s\_1+*e\_2×*s\_2mod\_n\_

4. 利用幂运算性质分解

*   根据幂运算的性质,可以将 *m\*\*e\_1×*s\_1+*e\_*s\_2 分解为 (*m\*\*e\_1×*s\_*m\*\*e\_2×*s\_2)mod\_n *,即:* m**e\_1×*s\_1+* e\_2×*s\_2mod\_n*=(\_m**e\_1×*s\_1mod\_n*×*m\*\*e\_*s\_2mod\_n *)mod\_n*

5. **代入已知值 **** ***** c ****** ***1 和 **** ***** c ****** *2

*   根据给定条件 *c\_1=*m**e\_1mod\_n\_ 和 \*c\_2=\*m**e\_2mod\_n *,我们有:* m\*\*e1×*s\_1mod\_n*=(\* c\_1)*s\_1mod\_n\_\_m\*\*e\_*s\_2mod\_n*=(*c\_2)* s\_2mod\_n*
*   将这些代入上一步的分解结果中:*m*=\[(*c\_1\_s\_1mod\_n*)×(*c\_2\_s\_2mod\_n*)]mod\_n\_

总结

这段推导展示了如何利用已知的 c_1 和 _c_2 以及它们对应的指数 _e_1 和 _e_2 来恢复明文 _m。通过巧妙地利用模运算的性质和指数的线性组合关系,可以将明文表示为 c_1 和 _c_2 的幂次方的乘积对模 _n 取模的结果。这种方法在密码学中常用于构建更灵活的安全协议,特别是在多密钥或同态加密的场景中

变式:e1、e2不互素 设gcd(e1, e2) = a,得到s1 * e1 + s2 * e2 = a 即最后求得的m还需要开a次根 1 2 // a, s1, s2 = gcdext(e1, e2) m1 = gmpy2.powmod(c1, s[1], n) m2 = gmpy2.powmod(c2, s[2], n) m = (m1 * m2) % n

while True: if iroot(m, a)[1]: m = iroot(m, a)[0] print(long_to_bytes(m)) break m += n //

RSA

公钥解析得到:n = 8693448229604811919066606200349480058890565601720302561721665405 8378322103517 e = 65537 大数分解得到:p = 285960468890451637935629440372639283459, q = 304008741604601924494328155975272418463

RSAROLL

分解质数n,得到p = 18443,q = 49891 将每个m拼接起来即可

坏蛋是雷宾

PK是公钥的意思,Rabin的公钥密码体制和RSA有点类似,公钥n=p*q,私钥就是p和q

加密过程由明文m在平方后与n求模得到c,其次就是二次同余的过程。解密的时候就求出密文的平方根在两个私钥模值(p或者q)下的同余即可。 即找到一个数,使得其平方值与密文对于模值n同余