密码学实战 - HTB baby quick maffs

615 阅读3分钟

概述

baby quick maffs是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点在于基本的模计算。

题目分析

相关的任务文件包括一个source.py源代码和output.txt文本文件。

source.py内容如下

#!/usr/bin/env python3
from secret import flag, p, q
from Crypto.Util.number import bytes_to_long
from random import randint

def partition_message(m, N):
    m1 = randint(1, N)
    parts = []
    remainder = 0
    while sum(parts) < m:
        if sum(parts) + m1 < m:
            parts.append(m1)
        else:
            remainder = m - sum(parts)
            parts.append(m1 + remainder)
    return (parts, remainder)


def encode(message, N):
    m = bytes_to_long(message)
    parts, remainder = partition_message(m, N)
    ciphers = [pow(c, 2, N) for c in parts]
    return (ciphers, remainder)

N = p * q
ciphers, remainder = encode(flag, N)

with open("output.txt", "w") as f:
    out = f'{N}\n{remainder}\n{ciphers}'
    f.write(out)

output.txt则给出了Nreminder以及c1c2c3的值。

结合如上数据,我们可以得到如下的关系式

reminder = m - 2 * m1

c1 = pow(m1, 2, N)

c2 = pow(m1, 2, N) 
   = c1

c3 = pow(m1 + remainder, 2, N) 
   = pow(m1 + m - 2 * m1, 2, N)
   = pow(m - m1, 2, N)

#解题过程

使用模数计算规则,可以通过如下步骤得到m

c3(mm1)2(modN)c3(m22mm1+m12)(modN)c3m(m2m1)+m12(modN)c3mreminder+c1(modN)c3c1mreminder(modN)(c3c1)reminder1m(modN)c3 \equiv (m - m_1) ^ 2 \pmod {N} \\ c3 \equiv (m^2 - 2*m*m_1 + m_1^2) \pmod {N} \\ c3 \equiv m * (m - 2*m_1) + m_1^2 \pmod {N} \\ c3 \equiv m * reminder + c1 \pmod {N} \\ c3 - c1 \equiv m * reminder \pmod {N} \\ (c3 - c1) * reminder^{-1} \equiv m \pmod {N} \\
from Crypto.Util.number import bytes_to_long, long_to_bytes 

N = 6083782486455360611313889289556658208725888944237734041722591252756006664878102248734673207367745303402874595854966731263105387801996693270011840173939423

reminder = 1081087287982224274239399953615475281184099226198643053396569433856757255106426461817760194704250226883807897800355728788149068771546876055268915238961343

c1 = 5408283916250636369066846815501131861319520431106165986129813106223074286810632222888292034380612581416458756909119954039579666773680866532576166358987272

c3 = 5598555010250184271123226314796180406367795504188162611960100902143581636125416986623404842897202277277978566659455918773104687212096435095590205751904580

m = ((c3 - c1) * pow(reminder, -1, N)) % N

print("FLAG =", long_to_bytes(m))