Beispiel #1
0
    def srp_authn(self, email, input_hmac):
        account = self.accounts[email]

        salt = account["salt"]
        salt_bytes = to_bytes(salt)

        A, b, u = account["A"], account["b"], account["u"]

        for password in WORDS:
            # Find x as in Steven's `hello` step/Carla's `kexch` step.
            x_bytes = sha256(salt_bytes + password.encode()).digest()
            x = from_bytes(x_bytes)

            # Find v as in Steven's `hello` step.
            v = modexp(self.g, x, self.n)

            # Find S and K as in Steven's `kexch` step.
            S = modexp(A * modexp(v, u, self.n), b, self.n)
            K = sha256(to_bytes(S)).digest()

            if hmac_sha256(K, salt_bytes) == input_hmac:
                return f"{email}, your password is '{password}'. Muahahaha!"

        # Password wasn't found in the dictionary.
        return f"These are not the droids you're looking for."
Beispiel #2
0
    def srp_kexch(self):
        a = random.getrandbits(1536)
        A = modexp(self.g, a, self.n)

        # Carol now receives u from Steve.
        self.salt, B, u = self.parley("kexch", self.email, A)

        x_bytes = sha256(to_bytes(self.salt) + self.password.encode()).digest()
        x = from_bytes(x_bytes)

        # k is not used anymore.
        S = modexp(B, a + u * x, self.n)

        self.K = sha256(to_bytes(S)).digest()
    def srp_kexch(self):
        a = random.getrandbits(1536)
        A = modexp(self.g, a, self.n)

        self.salt, B = self.parley("kexch", self.email, A)

        u_bytes = sha256(to_bytes(A, B)).digest()
        u = from_bytes(u_bytes)

        x_bytes = sha256(to_bytes(self.salt) + self.password.encode()).digest()
        x = from_bytes(x_bytes)

        S = modexp(B - self.k * modexp(self.g, x, self.n), a + u * x, self.n)

        self.K = sha256(to_bytes(S)).digest()
Beispiel #4
0
    def srp_kexch(self, email, A):
        account = self.accounts[email]

        b = random.getrandbits(1536)
        B = modexp(self.g, b, self.n)

        # u is now simply a random uint128.
        u = random.getrandbits(128)

        S = modexp(A * modexp(account["v"], u, self.n), b, self.n)

        account["K"] = sha256(to_bytes(S)).digest()

        # Steven now sends u to Carl.
        return account["salt"], B, u
    def rsa_echo(self, ctext):
        # Eve is actually MITMing, not just eavesdropping.
        # To simulate an eavesdrop, have Eve discard the plaintext.
        self.parley("echo", ctext)

        # Steve will reject repeat submissions.
        assert self.parley("echo", ctext) is None

        # Eve cracks the ciphertext on her own.
        C = from_bytes(ctext)
        E, N = self.remote_pubkey
        S = random.randint(2, N - 1)

        C_ = (C * modexp(S, E, N)) % N
        ptext_ = self.parley("echo", to_bytes(C_))
        P_ = from_bytes(ptext_)

        P = (P_ * invmod(S, N)) % N
        ptext = to_bytes(P)

        print("Eve cracked Carol's plaintext:")
        print()
        print(" " * 4 + ptext.decode())
        print()

        # Carol won't notice a thing :P
        return ptext
Beispiel #6
0
def decryptor(ctext, pubkey, oracle, show=True):
    e, n = pubkey
    two = modexp(2, e, n)

    # Decryption algorithm as described in the challenge.
    # Mostly works, but usually fails for the last character.
    #
    # lower, upper, ptext = 0, n, b""
    # while lower < upper:
    #     mid = (upper + lower) // 2
    #     if oracle(ctext):
    #         upper -= mid
    #     else:
    #         lower += mid
    # return to_bytes(upper)

    lower, upper, bit_length = 0, 1, n.bit_length()

    for i in range(1, bit_length + 1):
        diff, lower, upper = upper - lower, lower << 1, upper << 1
        ctext = (ctext * two) % n
        if oracle(ctext):
            upper -= diff
        else:
            lower += diff
        print("\r" + to_str((upper * n) >> i) + "\033[K", end="", flush=True)
    else:
        print()

    return to_bytes((upper * n) >> bit_length)
    def srp_kexch(self, email, A):
        account = self.accounts[email]

        b = random.getrandbits(1536)
        B = self.k * account["v"] + modexp(self.g, b, self.n)

        u_bytes = sha256(to_bytes(A, B)).digest()
        u = from_bytes(u_bytes)

        # We can't simply calculate the `A * v ** u` part of
        # `S = (A * v ** u) ** b % n`; the result is huge. But it seems
        # that all arithmetic is performed modulo n of late. *hint hint*
        S = modexp(A * modexp(account["v"], u, self.n), b, self.n)

        account["K"] = sha256(to_bytes(S)).digest()

        return account["salt"], B
    def srp_hello(self, email, password):
        salt = random.getrandbits(32)

        x_bytes = sha256(to_bytes(salt) + password.encode()).digest()
        x = from_bytes(x_bytes)

        v = modexp(self.g, x, self.n)

        self.accounts[email] = {"password": password, "salt": salt, "v": v}

        return self.n, self.g, self.k
def decrypt_pass(constants, state, oracle):
    e, n, c_0, s_0, B, B_2, B_3, B_31 = constants
    i, s_i1, M_i1 = state

    # Find s_i.
    if i == 1 or (i > 1 and len(M_i1) > 1):
        s_i = (n + B_31) // B_3 if i == 1 else s_i1 + 1
        while not oracle((c_0 * modexp(s_i, e, n)) % n):
            s_i += 1
    else:
        a, b = list(M_i1)[0]
        r_i = ((2 * (b * s_i1 - B_2)) + (n - 1)) // n
        while True:
            lower = (B_2 + (r_i * n) + (b - 1)) // b
            upper = (B_3 + (r_i * n) + (a - 1)) // a
            for s_i in range(lower, upper):
                if oracle((c_0 * modexp(s_i, e, n)) % n):
                    break
            else:
                r_i += 1
                continue
            break

    # Find M_i.
    M_i = set()

    for a, b in M_i1:
        lower = ((a * s_i) - B_31 + (n - 1)) // n
        upper = ((b * s_i) - B_2) // n
        for r in range(lower, upper + 1):
            a_i = (B_2 + (r * n) + (s_i - 1)) // s_i
            b_i = (B_31 + (r * n)) // s_i
            M_i.add((max(a, a_i), min(b, b_i)))

    if len(M_i) == 1:
        a, b = list(M_i)[0]
        if a == b:
            return (a * invmod(s_0, n)) % n

    state = (i + 1, s_i, M_i)
    return constants, state
def decrypt_prepare(ctext, pubkey, oracle):
    # Extract/precompute some numbers that show up often in the math.
    e, n = pubkey
    B = 1 << 8 * (byte_length(n) - 2)
    B_2, B_3, B_31 = 2 * B, 3 * B, 3 * B - 1
    M_0 = {(B_2, B_31)}

    for s_0 in range(1, n + 1):
        c_0 = (ctext * modexp(s_0, e, n)) % n
        if oracle(c_0):
            constants = (e, n, c_0, s_0, B, B_2, B_3, B_31)
            state = (1, s_0, M_0)
            return constants, state
def bruteforce_dsa_privkey(bs, sig, max_k=2**16, p=P, q=Q, g=G):
    r, s = sig
    z = from_bytes(SHA1(bs).digest())

    for k in range(1, max_k):
        k_inv = invmod(k, q)
        if k_inv is None:
            continue

        x = (((((s * k) % q) - z) % q) * invmod(r, q)) % q

        sk, rk = (k_inv * (z + x * r)) % q, modexp(g, k, p) % q
        if s == sk and r == rk:
            return x
Beispiel #12
0
def decryptor(ctext, pubkey, oracle, show=True):
    e, n = pubkey
    two = modexp(2, e, n)

    lower, upper, bit_length = 0, 1, n.bit_length()

    for i in range(1, bit_length + 1):
        diff, lower, upper = upper - lower, lower << 1, upper << 1
        ctext = (ctext * two) % n
        if oracle(ctext):
            upper -= diff
        else:
            lower += diff
        print("\r" + to_str((upper * n) >> i) + "\033[K", end="", flush=True)
    else:
        print()

    return to_bytes((upper * n) >> bit_length)
    def __init__(self, pubkey, privkey, ctext):
        orig_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
        self.pool = Pool(CPUS)
        signal.signal(signal.SIGINT, orig_handler)

        self.e, self.n = pubkey
        self.privkey = privkey

        # Save the modulus length for the progress indicator.
        self.bits = self.n.bit_length()

        # Find s_0 and save initial state.
        self.c_0 = ctext
        self.s_0 = self.s = self.mp_find_s(self.gen_incr(1))

        self.c_0 = (self.c_0 * modexp(self.s, self.e, self.n)) % self.n
        self.i = 0
        self.B = 1 << (byte_length(self.n) - 2) * 8
        self.M = {(self.B * 2, self.B * 3 - 1)}

        self.result = None
Beispiel #14
0
    def srp_kexch(self, email, A):
        account = self.accounts[email]

        # Mallory doesn't know the password or anything about it.
        account.pop("password")
        account.pop("v")

        # "Use arbitrary values for b, B, u, and salt". The way Steven
        # generates these is already arbitrary; just do as Steven does.
        # (We could fix b, u, and salt to values that simplify the math,
        # but the attack doesn't seem to hinge upon doing this.)
        b = random.getrandbits(1536)
        B = modexp(self.g, b, self.n)

        u = random.getrandbits(128)

        # Mallory needs to save A, b, and u for her `authn` step.
        account.update({"A": A, "b": b, "u": u})

        # A salt was already generated in Steven's `hello` step.
        return account["salt"], B, u
def mp_test_s(mp_data):
    c_0, s, e, n, privkey = mp_data
    if oracle((c_0 * modexp(s, e, n)) % n, privkey):
        return s