from Crypto.Util.number import * from gmpy2 import * from secret import flag p = getPrime(25) e = # Hidden q = getPrime(25) n = p * q m = bytes_to_long(flag.strip(b"npuctf{").strip(b"}")) c = pow(m, e, n) print(c) print(pow(2, e, n)) print(pow(4, e, n)) print(pow(8, e, n)) ''' 169169912654178 128509160179202 518818742414340 358553002064450 '''
from Crypto.Util.number import * from Crypto.Cipher import AES fp=open("flag_cipher.txt","rb") b=fp.read() print(len(b)) C=[] M=[] S="" for i inrange(0,len(b),32): C.append(b[i:i+32]) print(len(C)) for i inrange(52,0,-1): Enc=AES.new(C[i-1],AES.MODE_ECB) M=[Enc.decrypt(C[i])]+M S+=M[0].decode() print(S)
from gmpy2 import is_prime from os import urandom import base64 defbytes_to_num(b): returnint(b.encode('hex'), 16) defnum_to_bytes(n): b = hex(n)[2:-1] b = '0' + b iflen(b)%2 == 1else b return b.decode('hex') defget_a_prime(l): random_seed = urandom(l)
num = bytes_to_num(random_seed)
whileTrue: if is_prime(num): break num+=1 return num defencrypt(s, e, n): p = bytes_to_num(s) p = pow(p, e, n) return num_to_bytes(p).encode('hex') defseparate(n): p = n % 4 t = (p*p) % 4 return t == 1 f = open('flag.txt', 'r') flag = f.read() msg1 = "" msg2 = "" for i inrange(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)))
from Crypto.Util.number import * from base64 import * defseparate(n): p = n % 4 t = (p*p) % 4 return t == 1 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(b64decode(n2)) n3=bytes_to_long(b64decode(n3)) n1=2499586809914462821807624371088011200618603528498132509598946284572455726453497171635086810524607288333625665025664872216634366700044105279185519761587818169021167370991396691510275499486673922916370294043072503635630922980240462022218565365191228535222150496387990987123639567257124081274667568443678527637259644488779394704508217357758791670308548246801142468699716221789070607334747835552167450340441488756779323653879402176647890584656379628685893686585469918686253137796663587854943386347039389769790329948165162483370187914412810153613198247569427480466488647563900948387020677830797976534568626241686906738179 p=GCD(n1,n2) q1,q2=n1//p,n2//p phi1,phi2=(p-1)*(q1-1),(p-1)*(q2-1) d1,d2=inverse(0x1001,phi1),inverse(0x1001,phi2) c1=0x1240198b148089290e375b999569f0d53c32d356b2e95f5acee070f016b3bef243d0b5e46d9ad7aa7dfe2f21bda920d0ac7ce7b1e48f22b2de410c6f391ce7c4347c65ffc9704ecb3068005e9f35cbbb7b27e0f7a18f4f42ae572d77aaa3ee189418d6a07bab7d93beaa365c98349d8599eb68d21313795f380f05f5b3dfdc6272635ede1f83d308c0fdb2baf444b9ee138132d0d532c3c7e60efb25b9bf9cb62dba9833aa3706344229bd6045f0877661a073b6deef2763452d0ad7ab3404ba494b93fd6dfdf4c28e4fe83a72884a99ddf15ca030ace978f2da87b79b4f504f1d15b5b96c654f6cd5179b72ed5f84d3a16a8f0d5bf6774e7fd98d27bf3c9839 c2=0x129d5d4ab3f9e8017d4e6761702467bbeb1b884b6c4f8ff397d078a8c41186a3d52977fa2307d5b6a0ad01fedfc3ba7b70f776ba3790a43444fb954e5afd64b1a3abeb6507cf70a5eb44678a886adf81cb4848a35afb4db7cd7818f566c7e6e2911f5ababdbdd2d4ff9825827e58d48d5466e021a64599b3e867840c07e29582961f81643df07f678a61a9f9027ebd34094e272dfbdc4619fa0ac60f0189af785df77e7ec784e086cf692a7bf7113a7fb8446a65efa8b431c6f72c14bcfa49c9b491fb1d87f2570059e0f13166a85bb555b40549f45f04bc5dbd09d8b858a5382be6497d88197ffb86381085756365bd757ec3cdfa8a77ba1728ec2de596c5ab m1,m2=pow(c1,d1,n1),pow(c2,d2,n2) m1,m2=long_to_bytes(m1),long_to_bytes(m2) m1,m2=m1.decode(),m2.decode() s,n="",len(m1)+len(m2) po1,po2=0,0 for i inrange(n): if(separate(i)): s=s+m2[po2] po2+=1 else: s=s+m1[po1] po1+=1 print(s)
4.[NPUCTF2020]共 模 攻 击
PART 1
做题目时,发现题目给了一个hint,我们先打开看一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
from gmpy2 import * from Crypto.Util.number import * from secret import hint m = bytes_to_long(hint) p = getPrime(256) c = pow(m, 256, p) print(p) p, q = getPrime(256), getPrime(256) n = p * q e1, e2 = getPrime(32), getPrime(32) c1, c2 = pow(c, e1, n), pow(c, e2, n) print(n) print(e1, c1) print(e2, c2)
很显然,我们如果想解密这个hint,首先来的就是一次共模攻击,解出这个hint加密后的$c$值,然后我们就是要解同余方程$x^{256}\equiv c \pmod p$。发现$p$是素数,并且$\gcd(p-1,256)=4$,说明方程一共有$4$个根。我们可以直接利用Sagemath解$\text{GF}$域上的方程,得到$4$个解如下图,然后一个 一个通过long_to_bytes转换成字符,可以得到hint:m.bit_length()<400
PART 2
得到了hint之后,我们再进入正规的解题题目中来:
1 2 3 4 5 6 7 8 9 10 11 12
from gmpy2 import * from Crypto.Util.number import * from secret import flag flag = flag.strip(b"npuctf{").strip(b"}") m = bytes_to_long(flag) p, q = getPrime(512), getPrime(512) n = p * q e1, e2 = p, q c1, c2 = pow(m, e1, n), pow(m, e2, n) print(n) print(c1) print(c2)
根据之前在离散对数中探讨过的一个内容:在模$M$($M$不一定是素数)的意义下所有的$\mathrm{ord}(x)$均为$\phi(M)$的因数,所以我们可以得到: $$ m^p\equiv m \pmod p \Rightarrow m^p\equiv ap+m\pmod n $$ $$ m^q\equiv m \pmod q \Rightarrow m^q\equiv bq+m\pmod n $$
下面就是要想办法构造一下两个式子,很显然我们可以把这两个式子相乘和相加,那么就有下面两个算式 $$ F=m^p+m^q\equiv ap+bq+2m \pmod m $$ $$ G=m^pm^q=m^{p+q}\equiv m^2+m(ap+bq)+abpq \pmod n $$
由于$n=pq$,所以$G$式的最后一项有$abpq\equiv 0 \pmod n$,所以化简$G$式,有 $$ G \equiv m^2+m(ap+bq) \pmod n $$ $F$式子乘上$m$,得: $$ mF\equiv m(ap+bq)+2m^2 \pmod n $$ 再进行两步推导 $$ mF-G\equiv m^2\pmod n $$ $$ m^2-mF+G\equiv 0 \pmod n $$