コード例 #1
0
    def process(self, request: bytes) -> bool:
        """Processes a request. Returns a boolean representing whether the
        message was valid and successfully processed. Each request looks like:

            message || IV || MAC
        """
        assert len(
            request
        ) > BLOCK_SIZE * 2, 'Request must be at least two blocks long'

        MSG = request[:-BLOCK_SIZE * 2]
        IV = request[-BLOCK_SIZE * 2:-BLOCK_SIZE]
        MAC = request[-BLOCK_SIZE:]

        expected_mac = cbc_encrypt(MSG, key=self.K, iv=IV)[-BLOCK_SIZE:]
        if MAC != expected_mac:
            return False

        fields = self.get_fields(MSG)
        amount = int(fields['amount'])
        sender = int(fields['from'])
        receiver = int(fields['to'])

        # NOTE: I don't do _any_ checking to see whether or not an account has
        #       funds. Who cares about realism?
        self.accounts[sender] -= amount
        self.accounts[receiver] += amount

        return True
コード例 #2
0
def randcrypt():
    """
    Selects one of the strings above, at random, encrypts it using our random
    global key, and returns the ciphertext and iv.
    """
    msg = choice(POSSIBLE_INPUTS)

    iv = os.urandom(16)
    ciphertext = cbc_encrypt(msg, KEY, iv)

    return ciphertext, iv
コード例 #3
0
ファイル: cryptopals_34.py プロジェクト: gerhalt/cryptopals
    def recieve(self, msg: bytes, iv: bytes) -> bytes:
        """Recieves a message, decrypts it with A's key, and then re-encrypts
        with a new IV and returns

        Returns:
            (bytes, bytes): msg, iv tuple
        """
        s = modpow(self.A, self.b, self.p)
        k = dh_digest(s)
        plaintext = pkcs7_strip(cbc_decrypt(msg, k, iv))

        iv = os.urandom(16)
        return cbc_encrypt(plaintext, k, iv), iv
コード例 #4
0
ファイル: cryptopals_16.py プロジェクト: gerhalt/cryptopals
def encrypt(msg: bytes, key: bytes = None, iv: bytes = None) -> bytes:
    """ Sandwiches user input between two existing strings, surrounding any ';'
    or '=' characters in single quotes. Pads and encrypts in AES CBC using the
    random key and a random IV, then returns the encrypted messge.
    """
    # Fall back to module defaults for local tests
    key = key or KEY
    iv = iv or IV

    # I interpreted "quote out" to mean surround disallowed characters with
    # single quotes
    msg_str = msg.decode()
    msg = CLEAN_RE.sub(r"'\1'", msg_str)

    # Convert string (necessary for regex replacement) back to bytes
    msg = bytes(msg.encode())

    # Tack on the prefix and suffix
    msg = PREFIX + msg + SUFFIX

    return cbc_encrypt(msg, key, iv)
コード例 #5
0
def randcryptor(msg: bytes) -> bytes:
    """
    Encrypts the input with AES in either ECB or CBC, randomly.
    """
    # Pad the message with 5-10 random bytes
    padding = os.urandom(randint(5, 10))
    padded_msg = pkcs7_pad(padding + msg + padding, BLOCK_SIZE)

    # Generate a random key
    key = generate_aes_key()

    # Randomly choose whether to use ECB or CBC
    mode = 'cbc' if bool(randint(0, 1)) else 'ecb'
    if mode == 'cbc':
        iv = os.urandom(BLOCK_SIZE)
        encrypted_msg = cbc_encrypt(padded_msg, key, iv)
    else:  # ECB
        cipher = AES.new(key, AES.MODE_ECB)
        encrypted_msg = cipher.encrypt(padded_msg)

    return encrypted_msg, mode  # FOR TESTING ONLY
コード例 #6
0
ファイル: cryptopals_34.py プロジェクト: gerhalt/cryptopals
    print(
        'Challenge #34 - Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection'
    )

    p = 12345
    g = 5

    A, a = dh_key(p, g)
    echo = Echo(p, g, A)

    # Test basic echo
    plaintext = b'some plaintext'

    key = dh_digest(modpow(echo.B, a, p))
    iv = os.urandom(16)
    ciphertext = cbc_encrypt(plaintext, key, iv)
    resp_ciphertext, resp_iv = echo.recieve(ciphertext, iv)

    # The sent and recieved plaintexts should be identical, after padding is
    # stripped away
    resp_plaintext = pkcs7_strip(cbc_decrypt(resp_ciphertext, key, resp_iv))
    assert plaintext == resp_plaintext

    # MITM
    mitm = Middleman(p, g, A)

    plaintext = b'top secret, do not read'
    key = dh_digest(modpow(mitm.B, a, p))
    iv = os.urandom(16)
    ciphertext = cbc_encrypt(plaintext, key, iv)
    resp_ciphertext, resp_iv = mitm.recieve(ciphertext, iv)
コード例 #7
0
 def generate_mac(self, msg: bytes) -> bytes:
     """Returns the MAC of a given message.
     """
     return cbc_encrypt(msg, key=self.K, iv=self.IV)[-BLOCK_SIZE:]