title: Python PyCrypto encrypt/decrypt text files with AES
body: <p>I already have a working program, but the only thing that doesn't work is the <code>decrypt_file()</code> function I have. I can still copy the encrypted text from the file and put it in my <code>decrypt()</code> function and have it work, but when I try to use my supposed-to-be handy <code>decrypt_file()</code> function it throws an error. Now I know 99.999% sure that my <code>encrypt()</code> and <code>decrypt()</code> functions are fine, but there is something with the bytes and strings conversion when I read and encode the text file that throws an error; I just can't find the hangup. Please help!</p>
  
  <p>My Program:</p>
  
  <pre><code>from Crypto import Random
  from Crypto.Cipher import AES
  
  def encrypt(message, key=None, key_size=256):
      def pad(s):
          x = AES.block_size - len(s) % AES.block_size
          return s + ((bytes([x])) * x)
  
      padded_message = pad(message)
  
      if key is None:
          key = Random.new().read(key_size // 8)
  
      iv = Random.new().read(AES.block_size)
      cipher = AES.new(key, AES.MODE_CBC, iv)
  
      return iv + cipher.encrypt(padded_message)
  
  def decrypt(ciphertext, key):
      unpad = lambda s: s[:-s[-1]]
      iv = ciphertext[:AES.block_size]
      cipher = AES.new(key, AES.MODE_CBC, iv)
      plaintext = unpad(cipher.decrypt(ciphertext))[AES.block_size:]
  
      return plaintext
  
  def encrypt_file(file_name, key):
      f = open(file_name, 'r')
      plaintext = f.read()
      plaintext = plaintext.encode('utf-8')
      enc = encrypt(plaintext, key)
      f.close()
      f = open(file_name, 'w')
      f.write(str(enc))
      f.close()
  
  def decrypt_file(file_name, key):
      def pad(s):
          x = AES.block_size - len(s) % AES.block_size
          return s + ((str(bytes([x]))) * x)
  
      f = open(file_name, 'r')
      plaintext = f.read()
      x = AES.block_size - len(plaintext) % AES.block_size
      plaintext += ((bytes([x]))) * x
      dec = decrypt(plaintext, key)
      f.close()
      f = open(file_name, 'w')
      f.write(str(dec))
      f.close()
  
  
  
  key = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
  
  encrypt_file('to_enc.txt', key)
  </code></pre>
  
  <hr>
  
  <p>The text file I encrypted:</p>
  
  <pre><code>b';c\xb0\xe6Wv5!\xa3\xdd\xf0\xb1\xfd2\x90B\x10\xdf\x00\x82\x83\x9d\xbc2\x91\xa7i M\x13\xdc\xa7'
  </code></pre>
  
  <hr>
  
  <p>My error when attempting <code>decrypt_file</code>:</p>
  
  <pre><code>    Traceback (most recent call last):
    File "C:\Python33\testing\test\crypto.py", line 56, in &lt;module&gt;
      decrypt_file('to_enc.txt', key)
    File "C:\Python33\testing\test\crypto.py", line 45, in decrypt_file
      plaintext += ((bytes([x]))) * x
  TypeError: Can't convert 'bytes' object to str implicitly
  [Finished in 1.5s]
  </code></pre>
  
  <hr>
  
  <p>When I replace line 45 with: <code>plaintext += ((str(bytes([x])))) * x</code>, this is the error I get:</p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Python33\testing\test\crypto.py", line 56, in &lt;module&gt;
      decrypt_file('to_enc.txt', key)
    File "C:\Python33\testing\test\crypto.py", line 46, in decrypt_file
      dec = decrypt(plaintext, key)
    File "C:\Python33\testing\test\crypto.py", line 23, in decrypt
      plaintext = unpad(cipher.decrypt(ciphertext))[AES.block_size:]
    File "C:\Python33\lib\site-packages\Crypto\Cipher\blockalgo.py", line 295, in decrypt
      return self._cipher.decrypt(ciphertext)
  ValueError: Input strings must be a multiple of 16 in length
  [Finished in 1.4s with exit code 1]
  </code></pre>