Path: blob/master/attacks/ecb/plaintext_recovery_harder.py
2589 views
def _get_prefix_padding(encrypt_oracle, paddings):1check = b"\x01" * 322for i in range(16):3prefix_padding = paddings[16 - i]4c = encrypt_oracle(prefix_padding + check)5if c[16:32] == c[32:48]:6return prefix_padding789def attack(encrypt_oracle, unused_byte=0):10"""11Recovers a secret which is appended to a plaintext and encrypted using ECB.12In this scenario, the encryption oracle prepends a constant, random prefix (length 0 to 16) to the plaintext.13:param encrypt_oracle: the encryption oracle14:param unused_byte: a byte that's never used in the secret or random prefix15:return: the secret16"""17# 17 here because _get_prefix_padding needs paddings[16].18paddings = [bytes([unused_byte] * i) for i in range(17)]19prefix_padding = _get_prefix_padding(encrypt_oracle, paddings)20secret = bytearray()21while True:22padding = paddings[15 - (len(secret) % 16)]23p = bytearray(prefix_padding + padding + secret + b"0" + padding)24byte_index = len(prefix_padding) + len(padding) + len(secret)25end1 = 16 + len(padding) + len(secret) + 126end2 = end1 + len(padding) + len(secret) + 127for i in range(256):28p[byte_index] = i29c = encrypt_oracle(p)30if c[end1 - 16:end1] == c[end2 - 16:end2]:31secret.append(i)32break33else:34secret.pop()35break3637return bytes(secret)383940