Exemple #1
0
def run_srp_intended():
    """
    The original SRP protocol from challenge 38.
    """
    # SERVER (x, v)
    salt = random_bytes(16)
    x_serv = int.from_bytes(sha256(salt + password).digest(), "little")
    v = pow(g, x_serv, n)

    # CLIENT (I, A)
    a = randbelow(n)
    A = pow(g, a, n)

    # SERVER (B, u)
    b = randbelow(n)
    B = pow(g, b, n)
    u = int.from_bytes(random_bytes(16), "little")

    # CLIENT (x, S, K)
    x_clnt = int.from_bytes(sha256(salt + password).digest(), "little")
    S_clnt = pow(B, a + u * x_clnt, n)
    K_clnt = sha256(S_clnt.to_bytes(ceil(S_clnt.bit_length() / 8),
                                    "little")).digest()
    HMAC_clnt = pbkdf2_hmac("sha256", K_clnt, salt, 100000)

    # SERVER (S, K)
    S_serv = pow(A * pow(v, u, n), b, n)
    K_serv = sha256(S_serv.to_bytes(ceil(S_serv.bit_length() / 8),
                                    "little")).digest()
    HMAC_serv = pbkdf2_hmac("sha256", K_serv, salt, 100000)

    assert compare_digest(HMAC_clnt, HMAC_serv)
    print("Client and server digests matched.")
Exemple #2
0
def get_random_cipher():
    key = random_bytes(16)

    if randint(0, 1):
        return AES.MODE_ECB, AES.new(key, mode=AES.MODE_ECB)

    return AES.MODE_CBC, AES.new(key, mode=AES.MODE_CBC, iv=random_bytes(16))
Exemple #3
0
def encrypt_random():
    string = choice(STRINGS)

    key = random_bytes(16)
    iv = random_bytes(16)
    cipher = AES.new(key, mode=AES.MODE_CBC, iv=iv)
    return key, iv, cipher.encrypt(pad(string, 16))
Exemple #4
0
def run_srp_mitm():
    """
    The MITM protocol from challenge 38. Server does not know password, but wants to
    crack it using A's HMAC-SHA256.
    """
    # SERVER (x, v)
    salt = random_bytes(16)

    # CLIENT (I, A)
    a = randbelow(n)
    A = pow(g, a, n)

    # SERVER (B, u)
    b = randbelow(n)
    B = pow(g, b, n)
    u = int.from_bytes(random_bytes(16), "little")

    # CLIENT (x, S, K)
    x_clnt = int.from_bytes(sha256(salt + password).digest(), "little")
    S_clnt = pow(B, a + u * x_clnt, n)
    K_clnt = sha256(S_clnt.to_bytes(ceil(S_clnt.bit_length() / 8),
                                    "little")).digest()
    HMAC_clnt = pbkdf2_hmac("sha256", K_clnt, salt, 100000)

    # Server shouldn't have access to the following.
    del a
    del x_clnt
    del S_clnt
    del K_clnt

    # ATTACKER (Have: A, b, B, u, salt, HMAC_clnt)
    # Goal: Recover the password....... with dictionary attack.
    # wtf is this

    dictionary = ["a", "b", "c", "let", "cat", "dog", "me", "in", "out"]
    for num_words in range(1, 5):
        for perm in permutations(dictionary, r=num_words):
            cracked_password = "".join(perm).encode()

            x_mitm = int.from_bytes(
                sha256(salt + cracked_password).digest(), "little")
            v = pow(g, x_mitm, n)

            S_mitm = pow(A * pow(v, u, n), b, n)
            K_mitm = sha256(
                S_mitm.to_bytes(ceil(S_mitm.bit_length() / 8),
                                "little")).digest()
            HMAC_mitm = pbkdf2_hmac("sha256", K_mitm, salt, 100000)

            if compare_digest(HMAC_mitm, HMAC_clnt):
                assert password == cracked_password
                print("Password successfully cracked.")
                return

    print("Failed to crack password.")
    assert False
Exemple #5
0
 def _() -> bytes:
     '使用 os.urandom 产生一个指定长度的字节字符串'
     nonlocal size
     collision_count = 0
     while (b := random_bytes(size)) in cache:
         collision_count += 1
         if collision_count > max_collisions:
             warn(
                 f'get_random_bytes has been updated {size=}, {step=}, {max_collisions=}'
             )
             collision_count = 0
             size += step
             cache.clear()
Exemple #6
0
def diffie_hellman_mitm():
    message = b"example message~"
    print(f"DH'ing message: {message}")

    # Generate A's DH values.
    a = randbelow(p)
    A = pow(g, a, p)

    print("ACTION: A -> M :: Send `p, g, A`")

    A = p

    print("ACTION: M -> B :: Send `p, g, p`")

    # Generate B's DH values.
    b = randbelow(p)
    B = pow(g, b, p)

    print("ACTION: B -> M :: Send `B`")

    B = p

    print("ACTION: M -> A :: Send `p`")

    # Calculate DH shared key.
    shared_key_a = sha1(pow(B, a, p).to_bytes(1600, "little"))[:16]

    # Encrypt message with A's key.
    iv_a = random_bytes(16)
    cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_a)
    message_a = cipher.encrypt(message)

    print(f"ACTION: A -> M :: Send encrypted message: {message_a}")

    broken_key = sha1((0).to_bytes(1600, "little"))[:16]

    cipher = AES.new(broken_key, mode=AES.MODE_CBC, iv=iv_a)
    broken_message_a = cipher.decrypt(message_a)

    print(f"ACTION: M :: Decrypted A's message: {broken_message_a}")
    print(f"ACTION: M -> B :: Relay encrypted message: {message_a}")

    # Calculate DH shared key.
    shared_key_b = sha1(pow(A, b, p).to_bytes(1600, "little"))[:16]

    # Decrypt A's message with shared key.
    cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_a)
    decrypted_message_a = cipher.decrypt(message_a)

    print(f"ACTION: B :: Decrypted A's message: {decrypted_message_a}")

    iv_b = random_bytes(16)
    cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_b)
    message_b = cipher.encrypt(decrypted_message_a)

    print(f"ACTION: B -> M :: Send A's encrypted message back: {message_b}")

    cipher = AES.new(broken_key, mode=AES.MODE_CBC, iv=iv_b)
    broken_message_b = cipher.decrypt(message_b)

    print(f"ACTION: M :: Decrypted B's message: {broken_message_b}")
    print(f"ACTION: M -> A :: Relay encrypted message: {message_a}")

    cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_b)
    decrypted_message_b = cipher.decrypt(message_b)

    print(f"ACTION: A :: Decrypted B's message: {decrypted_message_b}")

    assert broken_message_a == broken_message_b == message
Exemple #7
0
def diffie_hellman_mitm(g):
    # Assume p & g have been sent, acknowledged, and tampered with.

    message = b"example message~"
    print(f"DH'ing message: {message} with g = {g}")

    # Generate A's DH values.
    a = randbelow(p)
    A = pow(g, a, p)

    print("ACTION: A -> B :: Send `A`")

    # Generate B's DH values.
    b = randbelow(p)
    B = pow(g, b, p)

    print("ACTION: B -> A :: Send `B`")

    # Calculate DH shared key.
    shared_key_a = make_aes_key(pow(B, a, p))

    # Encrypt message with A's key.
    iv_a = random_bytes(16)
    cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_a)
    message_a = cipher.encrypt(message)

    print(f"ACTION: A -> M :: Send encrypted message: {message_a}")

    if g == 1:
        broken_keys = [make_aes_key(1)]
    elif g == p:
        broken_keys = [make_aes_key(0)]
    elif g == p - 1:
        broken_keys = [make_aes_key(i) for i in [1, p - 1]]

    ciphers = [AES.new(key, mode=AES.MODE_CBC, iv=iv_a) for key in broken_keys]
    broken_messages_a = [c.decrypt(message_a) for c in ciphers]

    print(
        f"ACTION: M :: Decrypted A's message: {b' or '.join(broken_messages_a)}"
    )
    print(f"ACTION: M -> B :: Relay encrypted message: {message_a}")

    # Calculate DH shared key.
    shared_key_b = sha1(pow(A, b, p).to_bytes(1600, "little"))[:16]

    # Decrypt A's message with shared key.
    cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_a)
    decrypted_message_a = cipher.decrypt(message_a)

    print(f"ACTION: B :: Decrypted A's message: {decrypted_message_a}")

    iv_b = random_bytes(16)
    cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_b)
    message_b = cipher.encrypt(decrypted_message_a)

    print(f"ACTION: B -> M :: Send A's encrypted message back: {message_b}")

    ciphers = [AES.new(key, mode=AES.MODE_CBC, iv=iv_b) for key in broken_keys]
    broken_messages_b = [c.decrypt(message_b) for c in ciphers]

    print(
        f"ACTION: M :: Decrypted B's message: {b' or '.join(broken_messages_b)}"
    )
    print(f"ACTION: M -> A :: Relay encrypted message: {message_a}")

    cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_b)
    decrypted_message_b = cipher.decrypt(message_b)

    print(f"ACTION: A :: Decrypted B's message: {decrypted_message_b}")

    assert message in broken_messages_a
    assert message in broken_messages_b
Exemple #8
0
def encrypt(string):
    key_iv = random_bytes(16)
    cipher = AES.new(key_iv, mode=AES.MODE_CBC, iv=key_iv)
    return key_iv, cipher.encrypt(pad(string, 16))
Exemple #9
0
def encrypt_profile(email):
    key = random_bytes(16)
    iv = random_bytes(16)
    cipher = AES.new(key, mode=AES.MODE_CBC, iv=iv)
    return key, iv, cipher.encrypt(pad(profile_for(email).encode(), 16))
Exemple #10
0
def run_server():
    sock = socket.create_server(("127.0.0.1", PORT))

    # Agree on N=[NIST Prime], g=2, k=3, I (email), P (password)

    while True:
        print("Server: Waiting for client...")

        conn, _ = sock.accept()

        print("Server: Client connection accepted.")

        # Generate salt as random integer
        # Generate string xH=SHA256(salt|password)
        # Convert xH to integer x somehow (put 0x on hexdigest)
        # Generate v=g**x % N
        # Save everything but x, xH

        print("Server: Generating salt, x, v")

        salt = random_bytes(16)
        xH = sha256(salt + password).digest()
        x = int.from_bytes(xH, "little")
        v = pow(g, x, n)
        del xH, x

        # Receive I, A=g**a % N (a la Diffie Hellman)

        print("Server: Receiving A from client")

        A = int.from_bytes(conn.recv(1600), "little")

        # Send salt, B=kv + g**b % N

        print("Server: Sending salt, B to client")

        b = randbelow(n)
        B = k * v + pow(g, b, n)

        conn.send(salt)
        conn.send(B.to_bytes(1600, "little"))

        # Compute string uH = SHA256(A|B), u = integer of uH

        print("Server: Calculating u")

        uH = sha256((A + B).to_bytes(1600, "little")).digest()
        u = int.from_bytes(uH, "little")

        # Generate S = (A * v**u) ** b % N
        # Generate K = SHA256(S)

        print("Server: Calculating S, K")

        S = pow(A * pow(v, u, n), b, n)
        K = sha256(S.to_bytes(1600, "little")).digest()

        # Send "OK" if HMAC-SHA256(K, salt) validates

        print("Server: Receiving HMAC from client")

        hmac = pbkdf2_hmac("sha256", K, salt, 100000)
        client_hmac = conn.recv(32)

        if compare_digest(hmac, client_hmac):
            print("Server: HMAC validated!")
            conn.send(b"OK")
        else:
            print("Server: HMAC NOT validated :-(")
            conn.send(b"NOT OK")

        conn.close()
Exemple #11
0
def get_padding():
    return random_bytes(randint(5, 10))
Exemple #12
0
def generate_random_cipher():
    key = random_bytes(16)
    return AES.new(key, mode=AES.MODE_ECB)
Exemple #13
0
def determine_block_size(encrypter):
    resize_sizes = []
    prev_length = len(encrypter(b"A"))

    for i in range(2, 64):
        ciphertext = encrypter(b"A" * i)

        if len(ciphertext) != prev_length:
            resize_sizes.append(i)
            prev_length = len(ciphertext)

        if len(resize_sizes) == 2:
            return resize_sizes[1] - resize_sizes[0]


def pad(bytestring, boundary=16):
    return bytestring + (b"\x00" * (boundary - len(bytestring) % boundary))


if __name__ == "__main__":
    cipher = generate_random_cipher()
    prefix_size = randint(12, 36)
    prefix = random_bytes(prefix_size)
    encrypter = lambda text: cipher.encrypt(pad(prefix + text + string)
                                            )  # noqa

    assert determine_block_size(encrypter) == 16
    assert determine_prefix_size(encrypter, 16) == prefix_size

    print(decode_string(encrypter).rstrip(b"\x00").decode())
Exemple #14
0
def set_secret() -> str:
    secret = b32encode(random_bytes(20))
    with open(SECRET_FILE, 'wb') as f:
        f.write(secret)
    return secret
Exemple #15
0
 def random(self, bytes_len: int = 1) -> Tuple[bytes, str]:
     rb: bytes = random_bytes(bytes_len)
     return rb, self.encode(rb)
Exemple #16
0
    "VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==",
    "V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==",
    "V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==",
    "U2hlIHJvZGUgdG8gaGFycmllcnM/",
    "VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=",
    "QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=",
    "VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=",
    "V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=",
    "SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==",
    "U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==",
    "U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=",
    "VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==",
    "QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu",
    "SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=",
    "VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs",
    "WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=",
    "SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0",
    "SW4gdGhlIGNhc3VhbCBjb21lZHk7",
    "SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=",
    "VHJhbnNmb3JtZWQgdXR0ZXJseTo=",
    "QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=",
]

plaintexts = [b64decode(s) for s in STRINGS]

key = random_bytes(16)
nonce = random_bytes(16)
ciphertexts = [ctr_crypt(pt, key, nonce) for pt in plaintexts]

# Per instructions, attack this manually.
Exemple #17
0
def wrap_string(string):
    key = random_bytes(16)
    iv = random_bytes(16)
    cipher = AES.new(key, mode=AES.MODE_CBC, iv=iv)
    uinfo = prefix + quote(string).encode() + suffix
    return key, iv, cipher.encrypt(pad(uinfo, 16))