Ejemplo n.º 1
0
 def pkcs_conformant(c_param: int, s_param: int) -> bool:
     """
     Helper-Function to check for PKCS conformance.
     """
     pkcs_conformant.counter += 1
     return oracle.decrypt(i2osp(c_param * pow(s_param, e, n) % n, k))
Ejemplo n.º 2
0
 def pkcs_conformant(c_param: int, s_param: int) -> bool:
     """
     Helper-Function to check for PKCS conformance.
     """
     pkcs_conformant.counter += 1
     return oracle.decrypt(i2osp(c_param * pow(s_param, e, n) % n, k))
Ejemplo n.º 3
0
def bleichenbacher(oracle: Oracle):
    """
    Bleichenbacher's attack

    Good ideas taken from:
        http://secgroup.dais.unive.it/wp-content/uploads/2012/11/Practical-Padding-Oracle-Attacks-on-RSA.html
    """

    k, n, e = oracle.get_k(), oracle.get_n(), oracle.get_e()

    B = pow(2, 8 * (k - 2))
    B2 = 2 * B
    B3 = B2 + B

    @typecheck
    def pkcs_conformant(c_param: int, s_param: int) -> bool:
        """
        Helper-Function to check for PKCS conformance.
        """
        pkcs_conformant.counter += 1
        return oracle.decrypt(i2osp(c_param * pow(s_param, e, n) % n, k))

    pkcs_conformant.counter = 0

    cipher = os2ip(oracle.eavesdrop())

    assert (pkcs_conformant(cipher, 1))

    c_0 = cipher
    set_m_old = {(B2, B3 - 1)}
    i = 1

    s_old = 0
    while True:
        if i == 1:
            s_new = ceildiv(n, B3)
            while not pkcs_conformant(c_0, s_new):
                s_new += 1

        elif i > 1 and len(set_m_old) >= 2:
            s_new = s_old + 1
            while not pkcs_conformant(c_0, s_new):
                s_new += 1

        elif len(set_m_old) == 1:
            a, b = next(iter(set_m_old))
            found = False
            r = ceildiv(2 * (b * s_old - B2), n)
            while not found:
                for s in interval(ceildiv(B2 + r * n, b),
                                  floordiv(B3 - 1 + r * n, a)):
                    if pkcs_conformant(c_0, s):
                        found = True
                        s_new = s
                        break
                r += 1

        set_m_new = set()
        for a, b in set_m_old:
            r_min = ceildiv(a * s_new - B3 + 1, n)
            r_max = floordiv(b * s_new - B2, n)
            for r in interval(r_min, r_max):
                new_lb = max(a, ceildiv(B2 + r * n, s_new))
                new_ub = min(b, floordiv(B3 - 1 + r * n, s_new))
                if new_lb <= new_ub:  # intersection must be non-empty
                    set_m_new |= {(new_lb, new_ub)}

        print("Calculated new intervals set_m_new = {} in Step 3".format(
            set_m_new))

        if len(set_m_new) == 1:
            a, b = next(iter(set_m_new))
            if a == b:
                print("Calculated:     ", i2osp(a, k))
                print("Calculated int: ", a)
                print("Success after {} calls to the oracle.".format(
                    pkcs_conformant.counter))
                return a

        i += 1
        s_old = s_new
        set_m_old = set_m_new
Ejemplo n.º 4
0
def bleichenbacher(oracle: Oracle):
    """
    Bleichenbacher's attack

    Good ideas taken from:
        http://secgroup.dais.unive.it/wp-content/uploads/2012/11/Practical-Padding-Oracle-Attacks-on-RSA.html
    """

    k, n, e = oracle.get_k(), oracle.get_n(), oracle.get_e()

    B = pow(2, 8 * (k - 2))
    B2 = 2 * B
    B3 = B2 + B

    @typecheck
    def pkcs_conformant(c_param: int, s_param: int) -> bool:
        """
        Helper-Function to check for PKCS conformance.
        """
        pkcs_conformant.counter += 1
        return oracle.decrypt(i2osp(c_param * pow(s_param, e, n) % n, k))

    pkcs_conformant.counter = 0

    cipher = os2ip(oracle.eavesdrop())

    assert(pkcs_conformant(cipher, 1))

    c_0 = cipher
    set_m_old = {(B2, B3 - 1)}
    i = 1

    s_old = 0
    while True:
        if i == 1:
            s_new = ceildiv(n, B3)
            while not pkcs_conformant(c_0, s_new):
                s_new += 1

        elif i > 1 and len(set_m_old) >= 2:
            s_new = s_old + 1
            while not pkcs_conformant(c_0, s_new):
                s_new += 1

        elif len(set_m_old) == 1:
            a, b = next(iter(set_m_old))
            found = False
            r = ceildiv(2 * (b * s_old - B2), n)
            while not found:
                for s in interval(ceildiv(B2 + r*n, b), floordiv(B3 - 1 + r*n, a)):
                    if pkcs_conformant(c_0, s):
                        found = True
                        s_new = s
                        break
                r += 1

        set_m_new = set()
        for a, b in set_m_old:
            r_min = ceildiv(a * s_new - B3 + 1, n)
            r_max = floordiv(b * s_new - B2, n)
            for r in interval(r_min, r_max):
                new_lb = max(a, ceildiv(B2 + r*n, s_new))
                new_ub = min(b, floordiv(B3 - 1 + r*n, s_new))
                if new_lb <= new_ub:  # intersection must be non-empty
                    set_m_new |= {(new_lb, new_ub)}

        print("Calculated new intervals set_m_new = {} in Step 3".format(set_m_new))

        if len(set_m_new) == 1:
            a, b = next(iter(set_m_new))
            if a == b:
                print("Calculated:     ", i2osp(a, k))
                print("Calculated int: ", a)
                print("Success after {} calls to the oracle.".format(pkcs_conformant.counter))
                return a

        i += 1
        s_old = s_new
        set_m_old = set_m_new