Example #1
0
def decryption_via_oracle():
    encryption = cbc_encrypt_random_line()
    target_ciphertext = encryption[0]
    target_iv = encryption[1]
    target_blocks = slice_target(target_ciphertext, 16)
    plaintext = b""
    for i in range(len(target_blocks)):
        plaintext += recover_block_plaintext(target_blocks[i], target_iv)
        target_iv = target_blocks[i]
    return plaintext
Example #2
0
    def ctr(self, target):
        # Slice plaintext into blocks
        target_blocks = slice_target(target, self.keysize)
        # Initialize plaintext variable
        plaintext = b''
        # Slice target into blocks
        blocks = slice_target(target, 16)

        # Iterate on each block
        for i in range(len(blocks)):
            # Expand counter to 64 bit little endian
            block_counter = struct.pack('<Q', i)
            # Generate block stream
            # format=64 bit unsigned little endian nonce, 64 bit little endian block count (byte count / 16)
            block_stream = self.nonce + block_counter
            # Generate keystream
            ciphertext = self.cipher.encrypt(block_stream)
            # Generate plaintext
            plaintext += xor_strings(blocks[i], ciphertext[:len(blocks[i])])

        return plaintext
Example #3
0
 def ecb_encrypt(self, plaintext, key):
     # Slice plaintext into blocks
     plaintext_blocks = slice_target(plaintext, 16)
     # Initialize plaintext variable for padding
     plaintext_padded = b""
     # Apply PKCS7 Padding
     if len(plaintext_blocks[-1]) < 16:
         plaintext_blocks[-1] = pkcs7_padding(plaintext_blocks[-1], 16)
     # Add blocks together
     for i in plaintext_blocks:
         plaintext_padded += bytes(i)
     # Encrypt under given key
     return self.cipher.encrypt(plaintext_padded)
Example #4
0
    def cbc_decrypt(self, ciphertext):
        plaintext = b""
        ciphertext = slice_target(ciphertext, self.keysize)
        previous_block = self.iv
        plainblocks = [b"" for i in ciphertext]

        for i in range(len(ciphertext)):
            plainblocks[i] = xor_strings(self.cipher.decrypt(ciphertext[i]),
                                         previous_block)
            previous_block = ciphertext[i]

        for i in plainblocks:
            plaintext += i

        return plaintext
Example #5
0
    def ecb_decrypt(self, ciphertext, key):
        # Slice ciphertext into blocks
        ciphertext_blocks = slice_target(ciphertext, 16)
        # Initialize plaintext list for blocks
        plaintext_blocks = [b"" for i in range(len(ciphertext_blocks))]
        # Decrypt each block and add it to the plaintext list
        for i in range(len(ciphertext_blocks)):
            plaintext_blocks[i] = self.cipher.decrypt(ciphertext_blocks[i])

        # Get last block and identify padding
        padding = plaintext_blocks[-1][-1]
        # Remove padding from last block
        plaintext_blocks[-1] = plaintext_blocks[-1][:-padding]
        # Initialize plaintext variable
        plaintext = b""
        # Add blocks together
        for i in plaintext_blocks:
            plaintext += i
        return plaintext
Example #6
0
    def cbc_encrypt(self, plaintext):
        ciphertext = b""
        plaintext = slice_target(plaintext, self.keysize)
        previous_block = self.iv

        if len(plaintext[-1]) != self.keysize:
            plaintext[-1] = pkcs7_padding(plaintext[-1], self.keysize)

        cipherblocks = [b"" for i in plaintext]

        for i in range(len(plaintext)):
            cipherblocks[i] = self.cipher.encrypt(
                xor_strings(plaintext[i], previous_block))
            previous_block = cipherblocks[i]

        ciphertext = b""
        for i in cipherblocks:
            ciphertext += i

        return ciphertext
Example #7
0
def detect_ecb_mode(ciphertexts):
    result = []
    # Iterate through all ciphertexts
    for ciphertext in ciphertexts:
        # Break ciphertext in blocks of 16 bytes
        target = slice_target(ciphertext, 16)
        # Total number of block in a given cipher is the length of the list
        number_of_blocks = len(target)
        # Initialize a dictionary to keep tracks of repeating blocks
        distinct_blocks = {}
        # Iterate through all blocks
        for i in target:
            # Assign value 1 to each distinct blocks
            distinct_blocks[i] = 1
        # Total number of distinct blocks is the length of the dictionary
        number_of_distinct_blocks = len(distinct_blocks)

        # Look for only ciphertexts with repeating blocks
        if number_of_distinct_blocks < number_of_blocks:
            # Append result to the result list
            result.append(ciphertext)
    return result