def modified_xor_brute(ciphertext):
    """
    Bruteforce XOR keys to decrypt ciphertext
    We assume the plaintext is english text
    """
    MAX_BYTE = 2**8 - 1
    decryptions = []

    for key in range(MAX_BYTE):
        key_extended = bytearray([key] * len(ciphertext))

        try:
            plaintext = binascii.unhexlify(xor(ciphertext,
                                               key_extended)).decode('utf-8')
        except UnicodeDecodeError:
            continue
        else:
            if not is_printable(plaintext):
                continue

            # Due to the limitations of ChiSquared we need to make the plaintext uppercase and without whitespace + punctuation
            score = ChiSquared(frequency.english.unigrams)(remove(
                plaintext, string.whitespace + string.punctuation).upper())
            decryption = Decryption(plaintext, key, score)

            # This is a (flaw?) in lantern that punct + whitespace is removed when scoring, however because the score
            # calculation is based on length, this means that incorrect strings full of punctuation can out score
            # correct decryptions with mostly letters. Therefore, we modify the score by how many characters were
            # removed during scoring. I should probably fix this in latern
            decryption.score /= len(
                remove(plaintext, string.whitespace +
                       string.punctuation)) / len(plaintext)
            decryptions.append(decryption)

    return sorted(decryptions, reverse=True)
Beispiel #2
0
def repeating_xor(x, k):
    len_x = len(x)
    len_k = len(k)
    key = ba(k * math.ceil(float(len_x) / len_k))
    x = ba(x)

    return bytes_to_hex(ba(xor(x, key)))
def _score_key(byte_string, key):
    dif_score = 0
    xored = xor(byte_string, binascii.b2a_hex(key))
    rel_freqs = get_char_freqs(xored)
    for k in rel_freqs.keys():
        dif_score += abs(rel_freqs[k]-REL_ENG_CHAR_FREQS[k])**2
    return dif_score
Beispiel #4
0
def aes_cbc_decrypt(ct, key, iv):
    ct_chunks = chunk(ct, BLK_SZ)
    ct_chunks.insert(0, iv)
    pt = []

    for i in range(len(ct_chunks) - 1):
        # get ct block
        ct_blk = ct_chunks[i + 1]

        # decrypt
        dct_blk = decrypt_aes_ecb(ct_blk, key)

        # prev blk
        prev_blk = ct_chunks[i]

        # xor with previous block
        pt_blk = xor(dct_blk, prev_blk)

        # append to pt
        pt.append(pt_blk)

    pt_s = functools.reduce(lambda a, b: a + b, pt)

    # unpad
    return pkcs7_unpad(pt_s)
Beispiel #5
0
def vigenereCipher(msg, key):

    if type(msg) != bytes:
        raise TypeError("message defined as bytes not %s" %type(msg))
    
    n = len(msg)
    KEY = KeyExpansion(key, n)

    return xor(msg, KEY)
Beispiel #6
0
def guess_single_key(encrypted_bytes):
  best_score = 0
  best_key = None
  for n in range(255):
    this_score = score(xor(encrypted_bytes, [n]))
    if this_score > best_score:
      best_score = this_score
      best_key = chr(n)

  return best_key
Beispiel #7
0
def break_repkey_xor(ciphertext):
    """
    
    :param ciphertext: ciphertext as bytes encrypted with repeating key xor
    :return:           decrypted ciphertext as bytes      
    """
    smallest = determine_keysize(ciphertext)
    keysize = smallest[1]

    key = determine_key(keysize, ciphertext)
    return challenge2.xor(ciphertext, key), key
Beispiel #8
0
def bruteforce_single_byte(x):
    x = hex_to_bytearray(x)
    len_x = len(x)

    results = []

    for i in range(256):
        test = bytearray([i for _ in range(len_x)])
        xored_str = xor(x, test)
        try:
            xored_str = xored_str.decode('utf-8')
        except:
            results.append(100 * len(x))
            continue
        test_score = l1_english_dist(xored_str)
        results.append(test_score)

    min_result = min(results)
    min_char_idx = results.index(min_result)
    min_char = chr(min_char_idx)
    return min_char, xor(x, bytearray([min_char_idx for _ in range(len_x)]))
Beispiel #9
0
    def encrypt(self, msg):
        n = self._blocksize
        count = self._count
        ciphertext = b""

        blocks = [msg[i:i + n] for i in range(0, len(msg), n)]
        for b in blocks:
            form = struct.pack("Q", self._nonce) + struct.pack("Q", count)
            print("ALGORITHM", form)

            keystream = self._cipher.encrypt(form)

            if self._inc:
                count += 1

            if len(b) % n == 0:
                ciphertext += challenge2.xor(keystream, b)
            else:
                end = len(b)
                ciphertext += challenge2.xor(keystream[:end], b)

        return ciphertext
Beispiel #10
0
def cbc_dec(ciphertext, iv, key):
    blocksize = 16
    if len(iv) != blocksize:
        raise ValueError

    plaintext = b""
    prevBlock = iv
    for i in range(0, len(ciphertext), blocksize):
        decBlock = aes128ecb_dec(ciphertext[i:i + blocksize], key)
        plaintext += xor(prevBlock, decBlock)
        prevBlock = ciphertext[i:i + blocksize]

    return plaintext
def cbc_encrypt(message: bytes,
                key: bytes,
                iv: bytes,
                block_size: int = 16) -> bytes:
    assert len(message) % block_size == 0
    blocks = [
        message[x:x + block_size] for x in range(0, len(message), block_size)
    ]
    cipher = b""
    for block in blocks:
        intermediate = xor(block, iv)
        cipher_block = ecb_encrypt(intermediate, key)
        cipher += cipher_block
        iv = cipher_block
    return cipher
Beispiel #12
0
def hit(linebytes):
    """
    
    :param linebytes: hex string to brute force
    :return:          best brute force hit
    """
    best = (0.000, b'', b'')  # (score, text, key)
    for i in range(255):
        xord = challenge2.xor(linebytes, [i])
        score = etaoin_shrdlu(xord)

        if best[0] < score:
            best = (score, xord, i)

    return best
Beispiel #13
0
def cbc_enc(inputBytes, iv, key):
    blocksize = 16
    if len(iv) != blocksize:
        raise ValueError

    ciphertext = b""
    prevBlock = iv
    for i in range(0, len(inputBytes), blocksize):
        nextBlock = inputBytes[i:i + blocksize]
        a = xor(nextBlock, prevBlock)
        print(a)
        prevBlock = aes128ecb_enc(a, key)
        ciphertext += prevBlock

    return ciphertext
Beispiel #14
0
def freq_analysis_get_key(ciphertext):
    scores = {}
    for k in all_possible_keys:
        kstr = k*(len(ciphertext)//2)
        plaintext_candidate = xor(kstr, ciphertext)
        pc_chunked = [plaintext_candidate[i:i+2] for i in range(0, len(plaintext_candidate), 2)]
        score = score_chunk(pc_chunked)
        scores[k] = score
    lowest_score = sys.maxsize
    lowest_key = ""
    for k,v in scores.items():
        if float(v) < lowest_score:
            lowest_key = k
            lowest_score = v
    return lowest_key, lowest_score
def cbc_decrypt(cipher_text: bytes,
                key: bytes,
                iv: bytes,
                block_size: int = 16) -> bytes:
    assert len(cipher_text) % block_size == 0
    blocks = [
        cipher_text[x:x + block_size]
        for x in range(0, len(cipher_text), block_size)
    ]
    message = b""
    for block in blocks:
        intermediate = ecb_decrypt(block, key)
        plain = xor(intermediate, iv)
        iv = block
        message += plain
    return message
Beispiel #16
0
def main():
    BLOCK = 3
    key = os.urandom(16)
    oracle = AsciiOracle(key)

    # assume we know the oracle will add these to our text
    prefix = b"userdata="
    postfix = b";comment2=bacon"
    """ ATTACK """
    pad = BLOCK * 16 - (len(prefix) + len(postfix))
    message = b"A" * (pad - 1)  # subtract one to prevent extra padding
    ciphertext = oracle.encrypt(message)

    c0 = ciphertext[:16]
    dummytext = c0 + b"\x00" * 16 + c0

    corrupt = oracle.decrypt(dummytext)
    iv = challenge2.xor(corrupt[:16], corrupt[-16:])

    print("[*] Recovered key:", binascii.hexlify(iv))
Beispiel #17
0
def aes_cbc_encrypt(pt, key, iv):
    # pad if needed
    pt_padded = pkcs7_pad(pt, BLK_SZ)
    pt_chunks = chunk(pt_padded, BLK_SZ)

    prev_blk = iv
    ct_blks = []
    for pt_blk in pt_chunks:
        # xor with prev blk
        pt_xored = xor(prev_blk, pt_blk)

        # ECB encrypt
        ct_blk = encrypt_aes_ecb(pt_xored, key)
        ct_blks.append(ct_blk)

        # store as prev blk
        prev_blk = ct_blk

    ct_s = functools.reduce(lambda a, b: a + b, ct_blks)

    return ct_s
def breakSingleXOR(ciphertext):

    msg = ""
    highScore = -1
    k = -1

    n = len(ciphertext)
 #   possible = []
    for key in range(256):

        KEY = KeyExpansion(chr(key).encode(), n)
        plaintext =  xor(ciphertext, KEY).decode(errors="ignore")
  #      possible.append(plaintext)

        try:
            if plaintext[0] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
                score = commonLetterScore(plaintext)
                if score > highScore:
                    highScore = score
                    msg = plaintext
                    k = chr(key)
        except:
            pass
    return (msg, k, highScore)
Beispiel #19
0
from binascii import hexlify
from itertools import cycle

import challenge2

important_work = b"""Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"""
key = b'ICE'
should_come_to = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f'
assert hexlify(challenge2.xor(important_work, key)).decode() == should_come_to
def encrypt_rep_xor(plaintext, key):
    key_to_use = extend_key(plaintext,key)
    chunked_pt = [hex(ord(a))[2:4] if len(hex(ord(a))[2:4]) == 2 else "0"+hex(ord(a))[2:4] for a in plaintext]
    chunked_key = [hex(ord(k))[2:4] for k in key_to_use]
    encrypted = xor("".join(chunked_key), "".join(chunked_pt))
    return encrypted