编程语言
首页 > 编程语言> > 【CISCN2018-Crypto】 crackme-java解析

【CISCN2018-Crypto】 crackme-java解析

作者:互联网

今天闲着无事,于是翻到了buu密码学的最后一页,看到了一道名字带java的题,还是很亲切的,于是花了一点时间做出来了,发现网上相关的wp较少,于是有了这篇wp,一步一步分析。


1.原题

import java.math.BigInteger;
import java.util.Random;

public class Test1 {
    static BigInteger two =new BigInteger("2");
    static BigInteger p = new BigInteger("11360738295177002998495384057893129964980131806509572927886675899422214174408333932150813939357279703161556767193621832795605708456628733877084015367497711");
    static BigInteger h= new BigInteger("7854998893567208831270627233155763658947405610938106998083991389307363085837028364154809577816577515021560985491707606165788274218742692875308216243966916");

    /*
     Alice write the below algorithm for encryption.
     The public key {p, h} is broadcasted to everyone.
    @param val: The plaintext to encrypt.
        We suppose val only contains lowercase letter {a-z} and numeric charactors, and is at most 256 charactors in length.
    */
    public static String pkEnc(String val){
        BigInteger[] ret = new BigInteger[2];
        BigInteger bVal=new BigInteger(val.toLowerCase(),36);
        BigInteger r =new BigInteger(new Random().nextInt()+"");
        ret[0]=two.modPow(r,p);
        ret[1]=h.modPow(r,p).multiply(bVal);
        return ret[0].toString(36)+"=="+ret[1].toString(36);
    }

    /* Alice write the below algorithm for decryption. x is her private key, which she will never let you know.
    public static String skDec(String val,BigInteger x){
        if(!val.contains("==")){
            return null;
        }
        else {
            BigInteger val0=new BigInteger(val.split("==")[0],36);
            BigInteger val1=new BigInteger(val.split("==")[1],36);
            BigInteger s=val0.modPow(x,p).modInverse(p);
            return val1.multiply(s).mod(p).toString(36);
        }
    }
   */

    public static void main(String[] args) throws Exception {
        System.out.println("You intercepted the following message, which is sent from Bob to Alice:");
        System.out.println("a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco==2q17m8ajs7509yl9iy39g4znf08bw3b33vibipaa1xt5b8lcmgmk6i5w4830yd3fdqfbqaf82386z5odwssyo3t93y91xqd5jb0zbgvkb00fcmo53sa8eblgw6vahl80ykxeylpr4bpv32p7flvhdtwl4cxqzc");
        System.out.println("Please figure out the plaintext!");
    }
}

//a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco==2q17m8ajs7509yl9iy39g4znf08bw3b33vibipaa1xt5b8lcmgmk6i5w4830yd3fdqfbqaf82386z5odwssyo3t93y91xqd5jb0zbgvkb00fcmo53sa8eblgw6vahl80ykxeylpr4bpv32p7flvhdtwl4cxqzc

2.加解密算法分析

2 r M o d   p = C 1 ( h r M o d   p ) ∗ M = C 2 C = C 1 + C 2 2^{r} Mod\ p = C_{1}\\ (h^{r} Mod\ p) *M = C_{2}\\ C = C_{1}+C_{2} 2rMod p=C1​(hrMod p)∗M=C2​C=C1​+C2​

s = ( C 1 x M o d   p ) − 1 M o d   p M = ( C 2 ∗ s )   M o d   p s=(C_{1}^{x} Mod\ p)^{-1} Mod\ p\\ M=(C_{2}*s)\ Mod\ p s=(C1x​Mod p)−1Mod pM=(C2​∗s) Mod p

M = C 2 / ( p o w ( h , r , p ) ) M=C_{2}/(pow(h,r,p)) M=C2​/(pow(h,r,p))

3.r枚举攻击

from threading import Thread

p=11360738295177002998495384057893129964980131806509572927886675899422214174408333932150813939357279703161556767193621832795605708456628733877084015367497711
c1=int('a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco',36)

def calr(r0,pid):
    print("[Process%d]: start from %d" % (pid, r0))
    while r0 < 2**26*(pid+1):
        if pow(2,r0,p) == c1:
            f = open('r','w')
            f.write(r0)
            exit(0)
        r0+=1
        if r0 % 2**18 == 0:
            print('[Process%d]: now %d' % (pid, r0))
    print('[Process%d]: exited!' % pid)

for i in range(0,32):
    t = Thread(target=calr,args=(i*2**26,i))
    t.start()
152351913

4.解得明文

import base36

p = 11360738295177002998495384057893129964980131806509572927886675899422214174408333932150813939357279703161556767193621832795605708456628733877084015367497711
c1 = int('a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco',36)
c2 = int('2q17m8ajs7509yl9iy39g4znf08bw3b33vibipaa1xt5b8lcmgmk6i5w4830yd3fdqfbqaf82386z5odwssyo3t93y91xqd5jb0zbgvkb00fcmo53sa8eblgw6vahl80ykxeylpr4bpv32p7flvhdtwl4cxqzc', 36)
h = int("7854998893567208831270627233155763658947405610938106998083991389307363085837028364154809577816577515021560985491707606165788274218742692875308216243966916")
r = 152351913

print(base36.dumps(c2//pow(h,r,p)))
ciscncongratulationsthisisdesignedbyalibabasecurity424218533

ATFWUS 2021-06-09

标签:BigInteger,java,val,36,crackme,r0,CISCN2018,new,Mod
来源: https://blog.csdn.net/ATFWUS/article/details/117729006