title: Given the plaintext, ciphertext, and IV. Can I find a reused key?
body: <h1>Hey all</h1>
  <p>I'm stuck on a part of an assignment for one of my programming classes.
  I believe the solution is pretty straightforward, but for whatever reason I cannot grasp it.</p>
  <p>The goal of the assignment is to <strong>modify the ciphertext so that the dollar amount is strictly increased</strong>. The classes encrypt and decrypt are given and cannot be edited, code is added to attack. Attack acts as a middleman and retrieves the output from encrypt before decrypt is called. Note that the key is retrieved from a reused file, ergo the same key is used for each encrypt and decrypt. Also we can assume we know the layout of the message.</p>
  <p>My initial reaction was that because we know that the key is the same and because we have the plaintext, ciphertext, and IV in attack, there must be a simple solution to modifying the ciphertext. I've tried computing a new tag after modifying the ciphertext, but the ciphertext is dependent on previous input (IV) so that doesn't work. Am I right to assume there is a relatively simple solution?</p>
  <p><em>Note: Not necessarily looking for a fully coded answer, just want some guidance in the approach to this problem. TA office hours was a mess with everything online</em> :(</p>
  <p>Thanks!</p>
  <pre><code>
  #### EXAMPLE KEY #####
  2D7F8E92A8E7109258C879F878E12387
  ######################
  
  class encrypt
  
  import sys
  import os
  import Crypto.Cipher.AES
  import hashlib
  
  f = open(sys.argv[1], 'r')
  key = f.readline()
  key = bytes.fromhex(key[:32])
  f.close()
  
  message = \
  &quot;&quot;&quot;AMOUNT: $  10.00
  Originating Acc Holder: Doe
  Orgininating Acc #82123-098370
  
  I authorized the above amount to be transferred to the account #38108-443280
  held by a student at the National Bank of the Cayman Islands.
  &quot;&quot;&quot;
  
  iv = os.urandom(16)
  cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_CBC, IV=iv)
  ciphertext = cipher.encrypt(message.encode()).hex()
  tag = hashlib.sha256(message.encode()).hexdigest()
  print(iv.hex() + ciphertext + tag)
  
  </code></pre>
  <pre><code>class decrypt
  
  import sys
  import Crypto.Cipher.AES
  import hashlib
  
  f = open(sys.argv[1], 'r')
  key = f.readline()
  key = bytes.fromhex(key[:32])
  f.close()
  
  ciphertextWithTag = bytes.fromhex(sys.argv[2]) # bytes.fromhex($CT)
  
  if len(ciphertextWithTag) &lt; 16+16+32:
    print(&quot;Ciphertext is too short!&quot;)
    sys.exit(0)
  
  iv = ciphertextWithTag[:16]
  ciphertext = ciphertextWithTag[:len(ciphertextWithTag)-32]  # with iv
  tag = ciphertextWithTag[len(ciphertextWithTag)-32:]
  cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_CBC, IV=iv)
  plaintext = cipher.decrypt(ciphertext[16:]) # here [16:] has spare apart iv
  
  if tag.hex() != hashlib.sha256(plaintext).hexdigest():
     print(&quot;Invalid tag!&quot;)
  else:
     print(&quot;Verified message&quot;)
     print(plaintext.decode())
  </code></pre>
  <pre><code>class attack
  
  
  import sys
  
  ciphertextWithTag = bytes.fromhex(sys.argv[1])
  
  if len(ciphertextWithTag) &lt; 16+16+32:
    print(&quot;Ciphertext is too short!&quot;)
    sys.exit(0)
  
  iv = ciphertextWithTag[:16]
  ciphertext = ciphertextWithTag[:len(ciphertextWithTag)-32]
  tag = ciphertextWithTag[len(ciphertextWithTag)-32:]
  
  # TODO: Modify the input so the transfer amount is more lucrative to the recipient
  
  # TODO: Print the new encrypted message
  # you can change the print content if necessary
  print(ciphertext.hex() + tag.hex())
  </code></pre>