[QCTF2018]Xman-RSA

题目描述:

gqhb jbkl2 pbkhqw pt_kqpbd
gqhb ht pbkhqw zqreahb
pbkhqw urtd64adg ulwdt_wh_ezb(u):qdwzqe pew(u.dexhad('mdi'), 16)adg ezb_wh_ulwdt(e):u = mdi(e)[2:-1]u = '0' + u pg yde(u)%2 == 1 dytd uqdwzqe u.adxhad('mdi')adg jdw_r_kqpbd(y):qreahb_tdda = zqreahb(y)ezb = ulwdt_wh_ezb(qreahb_tdda)fmpyd Tqzd:pg pt_kqpbd(ezb):uqdrvezb+=1qdwzqe ezbadg dexqlkw(t, d, e):k = ulwdt_wh_ezb(t)k = khf(k, d, e)qdwzqe ezb_wh_ulwdt(k).dexhad('mdi') adg tdkrqrwd(e):k = e % 4w = (k*k) % 4qdwzqe w == 1g = hkde('gyrj.wiw', 'q')
gyrj = g.qdra()btj1 = ""
btj2 = ""
ghq p pe qrejd(yde(gyrj)):pg tdkrqrwd(p):btj2 += gyrj[p]dytd:btj1 += gyrj[p]k1 = jdw_r_kqpbd(128)
k2 = jdw_r_kqpbd(128)
k3 = jdw_r_kqpbd(128)
e1 = k1*k2
e2 = k1*k3
d = 0i1001
x1 = dexqlkw(btj1, d, e1)
x2 = dexqlkw(btj2, d, e2)
kqpew(x1)
kqpew(x2)d1 = 0i1001
d2 = 0i101
k4 = jdw_r_kqpbd(128)
k5 = jdw_r_kqpbd(128)
e3 = k4*k5
x1 = ezb_wh_ulwdt(khf(e1, d1, e3)).dexhad('mdi')
x2 = ezb_wh_ulwdt(khf(e1, d2, e3)).dexhad('mdi')
kqpew(x1)
kqpew(x2)kqpew(urtd64.u64dexhad(ezb_wh_ulwdt(e2)))
kqpew(urtd64.u64dexhad(ezb_wh_ulwdt(e3)))

讲真的,这种在加密脚本上在做一次加密还从来没遇到过。

仔细看一看,应该是简单替换密码。直接上词频分析quipqiup - cryptoquip and cryptogram solver

需要注意的是:词频分析的原理只是把常见词往密文里面套,这里毕竟是代码,和平常的语言不一样,有可能有部分字母替换是错的,需要改一改;还有换行符也要手动加一下

替换之后:

from gmpy2 import is_prime
from os import urandom
import base64def bytes_to_num(b):return int(b.encode('hex'), 16)
def num_to_bytes(n):b = hex(n)[2:-1]b = '0' + b if len(b) % 2 == 1 else breturn b.decode('hex')
def get_a_prime(l):random_Teed = urandom(l)num = bytes_to_num(random_Teed)while True:if is_prime(num):breaknum+= 1return numdef encrypt(s, e, n):p = bytes_to_num(s)p = pow(p, e, n)return num_to_bytes(p).encode('hex')
def separate(n):p = n % 4t = (p * p) % 4return t == 1
f = open('flag.txt', 'r')
flag = f.read()
msg1 = ""
msg2 = ""
for i in range(len(flag)):if  separate(i):msg2 += flag[i]else:msg1 += flag[i]
p1 = get_a_prime(128)
p2 = get_a_prime(128)
p3 = get_a_prime(128)
n1 = p1 * p2
n2 = p1 * p3
e = 0x1001
c1 = encrypt(msg1, e, n1)
c2 = encrypt(msg2, e, n2)
print(c1)
print(c2)
e1 = 0x1001
e2 = 0x101
p4 = get_a_prime(128)
p5 = get_a_prime(128)
n3 = p4 * p5
c1 = num_to_bytes(pow(n1, e1, n3)).encode('hex')
c2 = num_to_bytes(pow(n1, e2, n3)).encode('hex')
print(c1)
print(c2)
print(base64.b64encode(num_to_bytes(n2)))
print(base64.b64encode(num_to_bytes(n3)))

分析程序:

从外到里看:

第一阶段:

c1,c2c1,c2c1,c2共模加密,显然是共模攻击,且n3n3n3模数,e1,e2e1,e2e1,e2指数已知

注意一点需要base64解码并且使用bytes_to_long函数将n2,n3n2,n3n2,n3换做正常的整数形式。

最后得到明文n1n1n1

第二阶段:

利用公约数分解模数;很显然n1,n2n1,n2n1,n2有相同的素因子p1p1p1

分解模数之后就可以正常求解RSA了

得到msg1,msg2msg1,msg2msg1,msg2

第三阶段:

flagflagflag字段是按照separate()separate()separate()函数分割到了msg1,msg2msg1,msg2msg1,msg2中

分析这个函数,实际上这个函数是当遍历的字符序号为0,2时,该字符连接到msg1msg1msg1字符串变量,当遍历的字符序号时1,3时,该字符连接到msg2msg2msg2字符串变量。

另外,也可以直接用separate()separate()separate()​函数进行解密,原理是一样的

解密脚本:

from Crypto.Util.number import *
import gmpy2
import base64n2 = "PVNHb2BfGAnmxLrbKhgsYXRwWIL9eOj6K0s3I0slKHCTXTAUtZh3T0r+RoSlhpO3+77AY8P7WETYz2Jzuv5FV/mMODoFrM5fMyQsNt90VynR6J3Jv+fnPJPsm2hJ1Fqt7EKaVRwCbt6a4BdcRoHJsYN/+eh7k/X+FL5XM7viyvQxyFawQrhSV79FIoX6xfjtGW+uAeVF7DScRcl49dlwODhFD7SeLqzoYDJPIQS+VSb3YtvrDgdV+EhuS1bfWvkkXRijlJEpLrgWYmMdfsYX8u/+Ylf5xcBGn3hv1YhQrBCg77AHuUF2w/gJ/ADHFiMcH3ux3nqOsuwnbGSr7jA6Cw=="
n3 = "TmNVbWUhCXR1od3gBpM+HGMKK/4ErfIKITxomQ/QmNCZlzmmsNyPXQBiMEeUB8udO7lWjQTYGjD6k21xjThHTNDG4z6C2cNNPz73VIaNTGz0hrh6CmqDowFbyrk+rv53QSkVKPa8EZnFKwGz9B3zXimm1D+01cov7V/ZDfrHrEjsDkgK4ZlrQxPpZAPl+yqGlRK8soBKhY/PF3/GjbquRYeYKbagpUmWOhLnF4/+DP33ve/EpaSAPirZXzf8hyatL4/5tAZ0uNq9W6T4GoMG+N7aS2GeyUA2sLJMHymW4cFK5l5kUvjslRdXOHTmz5eHxqIV6TmSBQRgovUijlNamQ=="
c1_n = 0x2639c28e3609a4a8c953cca9c326e8e062756305ae8aee6efcd346458aade3ee8c2106ab9dfe5f470804f366af738aa493fd2dc26cb249a922e121287f3eddec0ed8dea89747dc57aed7cd2089d75c23a69bf601f490a64f73f6a583081ae3a7ed52238c13a95d3322065adba9053ee5b12f1de1873dbad9fbf4a50a2f58088df0fddfe2ed8ca1118c81268c8c0fd5572494276f4e48b5eb424f116e6f5e9d66da1b6b3a8f102539b690c1636e82906a46f3c5434d5b04ed7938861f8d453908970eccef07bf13f723d6fdd26a61be8b9462d0ddfbedc91886df194ea022e56c1780aa6c76b9f1c7d5ea743dc75cec3c805324e90ea577fa396a1effdafa3090
c2_n = 0x42ff1157363d9cd10da64eb4382b6457ebb740dbef40ade9b24a174d0145adaa0115d86aa2fc2a41257f2b62486eaebb655925dac78dd8d13ab405aef5b8b8f9830094c712193500db49fb801e1368c73f88f6d8533c99c8e7259f8b9d1c926c47215ed327114f235ba8c873af7a0052aa2d32c52880db55c5615e5a1793b690c37efdd5e503f717bb8de716303e4d6c4116f62d81be852c5d36ef282a958d8c82cf3b458dcc8191dcc7b490f227d1562b1d57fbcf7bf4b78a5d90cd385fd79c8ca4688e7d62b3204aeaf9692ba4d4e44875eaa63642775846434f9ce51d138ca702d907849823b1e86896e4ea6223f93fae68b026cfe5fa5a665569a9e3948a
c1 = 0x1240198b148089290e375b999569f0d53c32d356b2e95f5acee070f016b3bef243d0b5e46d9ad7aa7dfe2f21bda920d0ac7ce7b1e48f22b2de410c6f391ce7c4347c65ffc9704ecb3068005e9f35cbbb7b27e0f7a18f4f42ae572d77aaa3ee189418d6a07bab7d93beaa365c98349d8599eb68d21313795f380f05f5b3dfdc6272635ede1f83d308c0fdb2baf444b9ee138132d0d532c3c7e60efb25b9bf9cb62dba9833aa3706344229bd6045f0877661a073b6deef2763452d0ad7ab3404ba494b93fd6dfdf4c28e4fe83a72884a99ddf15ca030ace978f2da87b79b4f504f1d15b5b96c654f6cd5179b72ed5f84d3a16a8f0d5bf6774e7fd98d27bf3c9839
c2 = 0x129d5d4ab3f9e8017d4e6761702467bbeb1b884b6c4f8ff397d078a8c41186a3d52977fa2307d5b6a0ad01fedfc3ba7b70f776ba3790a43444fb954e5afd64b1a3abeb6507cf70a5eb44678a886adf81cb4848a35afb4db7cd7818f566c7e6e2911f5ababdbdd2d4ff9825827e58d48d5466e021a64599b3e867840c07e29582961f81643df07f678a61a9f9027ebd34094e272dfbdc4619fa0ac60f0189af785df77e7ec784e086cf692a7bf7113a7fb8446a65efa8b431c6f72c14bcfa49c9b491fb1d87f2570059e0f13166a85bb555b40549f45f04bc5dbd09d8b858a5382be6497d88197ffb86381085756365bd757ec3cdfa8a77ba1728ec2de596c5abn2 = bytes_to_long(base64.b64decode(n2.encode("utf8")))
n3 = bytes_to_long(base64.b64decode(n3.encode("utf8")))
#第一阶段
e1 = 0x1001
e2 = 0x101
_,s,t = gmpy2.gcdext(e1,e2)
n1 = pow(c1_n,s,n3) * pow(c2_n,t,n3) % n3
#第二阶段
p1 = gmpy2.gcd(n1,n2)
p2 = n1 // p1
p3 = n2 // p1
e = 0x1001
fai_n1 = (p1-1)*(p2-1)
fai_n2 = (p1-1)*(p3-1)
d1 = gmpy2.invert(e,fai_n1)
d2 = gmpy2.invert(e,fai_n2)
m1 = pow(c1,d1,n1)
m2 = pow(c2,d2,n2)
m1 = long_to_bytes(m1)
m2 = long_to_bytes(m2)
# 第三阶段
msg1 = bytes.decode(m1.strip())
msg2 = bytes.decode(m2.strip())
length = len(msg1) + len(msg2)
print(msg1)
print(msg2)
flag = ""
count1 = count2 = 0
for i in range(length):if i % 4 == 0 or i % 4 == 2:flag += msg1[count1]count1 += 1if i % 4 == 1 or i % 4 == 3:flag += msg2[count2]count2 += 1
# 使用separate函数解密
# def separate(n):
#     p = n % 4
#     t = (p * p) % 4
#     return t == 1
# for i in range(length):
#     if separate(i):
#         flag += msg2[count2]
#         count2 += 1
#     else:
#         flag += msg1[count1]
#         count1 += 1
print(flag)

小结:

对于字节变量转换为字符串变量,我们可以使用:

bytes.decode(c)

进行转换

同时这种转换之后字节变量最后的/n/n/n还是存在

为了消除换行符可以使用

bytes.decode(c.strip())

另外一种转字节变量为字符串变量的方式:

直接使用str()函数,但是会有很多多余的字符需要切片(不是很推荐)

b’XA{RP0I_0Itrsigi s.y\n’

Crypto_[QCTF2018]Xman-RSA相关推荐

  1. RSA 2022/8/17

    1. [De1CTF2019]babyrsa(综合rsa) orz- 分步做: 1. 求p n = [2012961535249176549934011294318831718054876159786 ...

  2. golang通过RSA算法生成token,go从配置文件中注入密钥文件,go从文件中读取密钥文件,go RSA算法下token生成与解析;go java token共用

    RSA算法 token生成与解析 本文演示两种方式,一种是把密钥文件放在配置文件中,一种是把密钥文件本身放入项目或者容器中. 下面两种的区别在于私钥公钥的初始化, init方法,需要哪种取哪种. 通过 ...

  3. RSA签名算法,计算调用加密报文,安全传输

    RSA签名算法 1. 获取当前的时间戳参数 2. 计算参数签名 3. 获取请求对象的MD5密文 4. 通过私钥计算某个参数的RSA签名 5. 转换字符集到utf8 6. MD5加密字符串 7. bas ...

  4. RSA、MD5等加密算法的区别和应用

    RSA算法: 是典型的非对称加密算法,主要具有数字签名和验签的功能. MD5算法: 是消息摘要算法,只能用来生成消息摘要无法进行数字签名. IDEA算法和RC4算法: 对称加密算法,只能用来进行数据加 ...

  5. java签名算法阻止 设置_java数字签名算法之RSA

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml xsi:schemaLocation="http://maven.apache.org/POM/4. ...

  6. php+rsa生成签名sign,PHP 做 RSA 签名 生成订单(支付宝例子)

    /组合签名 $a=time(); $b=substr($a, 1); //生成随机订单号 $orderid= $b.mt_rand(10000,99999); //合作身份者id,以2088开头的16 ...

  7. rsa证书ssh登陆服务器

    好久不用,又生疏了. 今晚实操了一下,作一个记录. 使用rsa的密钥对登陆linux服务器,主要是为了安全. 这种证书级别的登陆,比最复杂的root用户名和帐号的安全性都要高一个等级. 至少服务器不会 ...

  8. 非对称加密算法RSA公钥私钥的模数和指数提取方法

    生成非对称加密算法RSA公钥.私钥的方法: 1. 通过OpenSSL库生成,可参考  https://github.com/fengbingchun/OpenSSL_Test/blob/master/ ...

  9. 非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例

    RSA算法,在1977年由Ron Rivest.Adi Shamirh和LenAdleman,在美国的麻省理工学院开发完成.这个算法的名字,来源于三位开发者的名字.RSA已经成为公钥数据加密标准. R ...

  10. 支付宝 php rsa算法,:PHP支付宝接口RSA验证

    这两天一直困扰的PHP RSA签名验证问题终于解决了,由于之前RSA接触的不多,再加上官方至今还未有PHP的SDK可供参考,因此走了一些弯路,写在这里和大家分享. 虽然支付宝官方还未提供相关SDK,P ...

最新文章

  1. 解决jQuery聚焦时光标在input最前面的问题
  2. PST转换软件 v6.3
  3. Python3 日期与时间戳相互转换
  4. 【重难点】【JUC 05】线程池核心设计与实现、线程池使用了什么设计模式、要你设计的话,如何实现一个线程池
  5. Windows 7密码重设盘的内部原理浅析
  6. [转载] New Concept English 1——Lesson 8 What's your job?
  7. 6421B Lab11 为分支机构优化数据访问
  8. tl-wdr5620千兆版设置虚拟服务器,TL-WDR5620路由器如何设置 TL-WDR5620路由器上网设置步骤【介绍】...
  9. c 转易语言源码,易语言代码转HTML 测试(源码方式)
  10. VMware Workstation Pro 导出OVF模板
  11. 打印机服务器总是自动停止,win7系统print spooler服务总是自动停止怎么办
  12. SolidWorks修改工程图中文字字体的方法
  13. gateway 动态路由
  14. 计算机桌面出现家庭组,win7系统桌面突然多出一个家庭组图标的解决方法
  15. how-to-solve-the-specific-problem,learn-this,imitate-this
  16. 百度数据可视化Sugar BI — 数据监控与预警(附保姆级教程)
  17. java mybatis优点_mybatis优缺点是什么?有哪些优点和缺点?
  18. PS调整边缘工具详解
  19. echarts的词云图
  20. 【JavaScript】- 打地鼠游戏(定时器嵌套延时器)

热门文章

  1. 关于通过邮箱找回密码的实现
  2. 《数学之美与浪潮之巅》读后感
  3. linux下10款markdown软件
  4. iOS申请证书,Certificates, Identifiers Profiles 简介
  5. mybatis@Param的作用
  6. Ubuntu 20.04 从零开始安装MySQL 8.0并重置root密码
  7. 在前端如何玩转 Word 文档
  8. 使用ntsd命令强制性杀掉进程[微软未开公的密秘]
  9. 用好工具,在团队协作中运筹帷幄
  10. 谍影追踪:全球首例UEFI_BIOS木马分析