[QCTF2018]Xman-RSA

题目分析

这道题上来先把加密脚本用单表替换密码加密了,解开后又分为共模攻击和p为n1,n2公因数的两种类型RSA,解出密文后有一个对明文顺序的加密。

解题

频率分析

分析出来的脚本有个别地方不准确,手动更改一下

from gmpy2 import is_prime 
from os import urandom 
import base64 
def 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 b 
    return b.decode('hex') 
def get_a_prime(l): 
    random_seed = urandom(l) 
    num = bytes_to_num(random_seed) 
    while True: 
        if is_prime(num): 
            break 
        num+=1 
    return num 
def 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 % 4 
    t = (p*p) % 4 
    return 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)))

解题

①从题中可以看出,n1和n2的公因数为p1,我们只要知道p1,p2,p3这三个数,就可以求解得到msg1和msg2,,题中所给的文件里并没有给出n1,解出n1成为了解题的关键。

p1=gcd(n1,n2)
p2=n1//p1
p3=n2//p1
e = 0x1001
d1=invert(e,(p1-1)*(p2-1))
d2=invert(e,(p1-1)*(p3-1))
msg1=pow(c3,d1,n1)
msg2=pow(c4,d2,n2)

②向后看可以发现,后边关于n1的加密是共模攻击,按照共模攻击的套路解出n1

e1 = 0x1001 
e2 = 0x101 
s1,s2=exgcdmoni.exgcd(e1,e2)
n1=powmod(c1,s1,n3)*powmod(c2,s2,n3)%n3

③解出msg1和msg2,把加密函数逆回去,这里需要m1和m2两个计数器,分别控制msg1和msg2

msg1=(long_to_bytes(msg1)).decode()
msg2=(long_to_bytes(msg2)).decode()
def separate(n): 
    p = n % 4 
    t = (p*p) % 4 
    return t == 1
flag=''
m1=0
m2=0
for i in range(0,len(msg1)+len(msg2)):
    if separate(i):
        flag+=msg2[m1]
        m1+=1
    else:
        flag+=msg1[m2]
        m2+=1
print(flag)

完整代码

from gmpy2 import *
from Crypto.Util.number import *
import base64,exgcdmoni
c1=0x2639c28e3609a4a8c953cca9c326e8e062756305ae8aee6efcd346458aade3ee8c2106ab9dfe5f470804f366af738aa493fd2dc26cb249a922e121287f3eddec0ed8dea89747dc57aed7cd2089d75c23a69bf601f490a64f73f6a583081ae3a7ed52238c13a95d3322065adba9053ee5b12f1de1873dbad9fbf4a50a2f58088df0fddfe2ed8ca1118c81268c8c0fd5572494276f4e48b5eb424f116e6f5e9d66da1b6b3a8f102539b690c1636e82906a46f3c5434d5b04ed7938861f8d453908970eccef07bf13f723d6fdd26a61be8b9462d0ddfbedc91886df194ea022e56c1780aa6c76b9f1c7d5ea743dc75cec3c805324e90ea577fa396a1effdafa3090
c2=0x42ff1157363d9cd10da64eb4382b6457ebb740dbef40ade9b24a174d0145adaa0115d86aa2fc2a41257f2b62486eaebb655925dac78dd8d13ab405aef5b8b8f9830094c712193500db49fb801e1368c73f88f6d8533c99c8e7259f8b9d1c926c47215ed327114f235ba8c873af7a0052aa2d32c52880db55c5615e5a1793b690c37efdd5e503f717bb8de716303e4d6c4116f62d81be852c5d36ef282a958d8c82cf3b458dcc8191dcc7b490f227d1562b1d57fbcf7bf4b78a5d90cd385fd79c8ca4688e7d62b3204aeaf9692ba4d4e44875eaa63642775846434f9ce51d138ca702d907849823b1e86896e4ea6223f93fae68b026cfe5fa5a665569a9e3948a
c3=0x1240198b148089290e375b999569f0d53c32d356b2e95f5acee070f016b3bef243d0b5e46d9ad7aa7dfe2f21bda920d0ac7ce7b1e48f22b2de410c6f391ce7c4347c65ffc9704ecb3068005e9f35cbbb7b27e0f7a18f4f42ae572d77aaa3ee189418d6a07bab7d93beaa365c98349d8599eb68d21313795f380f05f5b3dfdc6272635ede1f83d308c0fdb2baf444b9ee138132d0d532c3c7e60efb25b9bf9cb62dba9833aa3706344229bd6045f0877661a073b6deef2763452d0ad7ab3404ba494b93fd6dfdf4c28e4fe83a72884a99ddf15ca030ace978f2da87b79b4f504f1d15b5b96c654f6cd5179b72ed5f84d3a16a8f0d5bf6774e7fd98d27bf3c9839
c4=0x129d5d4ab3f9e8017d4e6761702467bbeb1b884b6c4f8ff397d078a8c41186a3d52977fa2307d5b6a0ad01fedfc3ba7b70f776ba3790a43444fb954e5afd64b1a3abeb6507cf70a5eb44678a886adf81cb4848a35afb4db7cd7818f566c7e6e2911f5ababdbdd2d4ff9825827e58d48d5466e021a64599b3e867840c07e29582961f81643df07f678a61a9f9027ebd34094e272dfbdc4619fa0ac60f0189af785df77e7ec784e086cf692a7bf7113a7fb8446a65efa8b431c6f72c14bcfa49c9b491fb1d87f2570059e0f13166a85bb555b40549f45f04bc5dbd09d8b858a5382be6497d88197ffb86381085756365bd757ec3cdfa8a77ba1728ec2de596c5ab
n2='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=='
n2=bytes_to_long(base64.b64decode(n2))
n3=bytes_to_long(base64.b64decode(n3))
e1 = 0x1001 
e2 = 0x101 
s1,s2=exgcdmoni.exgcd(e1,e2)
n1=powmod(c1,s1,n3)*powmod(c2,s2,n3)%n3
p1=gcd(n1,n2)
p2=n1//p1
p3=n2//p1
e = 0x1001
d1=invert(e,(p1-1)*(p2-1))
d2=invert(e,(p1-1)*(p3-1))
msg1=pow(c3,d1,n1)
msg2=pow(c4,d2,n2)
msg1=(long_to_bytes(msg1)).decode()
msg2=(long_to_bytes(msg2)).decode()
def separate(n): 
    p = n % 4 
    t = (p*p) % 4 
    return t == 1
flag=''
m1=0
m2=0
for i in range(0,len(msg1)+len(msg2)):
    if separate(i):
        flag+=msg2[m1]
        m1+=1
    else:
        flag+=msg1[m2]
        m2+=1
print(flag)

遇到的问题

这里发现字节类型的直接对其索引,会返回Int型数值

b=b'adkfh'
print(b[0])
>>97

所以最后一步解密时记得转成字符串

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 近期因为一些比赛以及其他原因,总结了一些RSA方面的东西,于是在这里与大家分享,希望大家能有所收获,如有不当之处敬...
    readilen阅读 17,257评论 1 11
  • 一、概述二、对称加密三、RSA加密四、OpenSSL使用 一、概述 RSA是一种非对称加密算法,1977年由罗纳德...
    yahibo阅读 595评论 0 8
  • RSA介绍 RSA 加密算法是一种非对称加密算法。在公开密钥加密和电子商业中 RSA 被广泛使用。RSA 算法的可...
    懒猫饼阅读 3,858评论 0 0
  • 一、RSA的历史 1976 年以前,所有的加密方法都是同一种模式: (1)甲方选择某一种加密规则,对信息进行加密;...
    开着保时捷堵你家门口阅读 2,316评论 0 1
  • Hi 这儿顾知寒 也是阿漓 ^02中秋/坐标江西九江/17年高一 ^目标:中山大学 ✨八月长安是我的光 更是人类之...
    是知寒呀呀呀阅读 423评论 0 0