title: Python 3 Unicode Objects must be encoded before hashing
body: <p>I use this code for hashing and salt: </p>
  
  <pre><code>def make_hash(password):
  """Generate a random salt and return a new hash for the password."""
  if isinstance(password, str):
      password = password.encode('utf-8')
  salt = b64encode(urandom(SALT_LENGTH))
  print (salt, type(salt))
  #print (salt.encode('utf-8'), type(salt.encode('utf-8')))
  return 'PBKDF2${}${}${}${}'.format(
      HASH_FUNCTION,
      COST_FACTOR,
      salt,
      b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
                           getattr(hashlib, HASH_FUNCTION))))
  </code></pre>
  
  <p>Here is the pbkdf2_bin:</p>
  
  <pre><code>def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
  """Returns a binary digest for the PBKDF2 hash algorithm of `data`
  with the given `salt`.  It iterates `iterations` time and produces a
  key of `keylen` bytes.  By default SHA-1 is used as hash function,
  a different hashlib `hashfunc` can be provided.
  """
  hashfunc = hashfunc or hashlib.sha1
  mac = hmac.new(data, None, hashfunc)
  def _pseudorandom(x, mac=mac):
      h = mac.copy()
      h.update(x)
      return map(int, h.digest())
  buf = []
  for block in range(1, -(-keylen // mac.digest_size) + 1):
      rv = u = _pseudorandom(salt + _pack_int(block))
      for i in range(iterations - 1):
          u = _pseudorandom(''.join(map(chr, u)))
          rv = starmap(xor, zip(rv, u))
      buf.extend(rv)
  return ''.join(map(chr, buf))[:keylen]
  </code></pre>
  
  <p>I already adjusted some things as:</p>
  
  <p>I replaced <code>unicode -&gt; str</code></p>
  
  <p>I replaced <code>izip -&gt; zip</code></p>
  
  <p>I changed this <code>map(ord, h.digest()) -&gt; map(int, h.digest())</code></p>
  
  <hr>
  
  <p>For python 2 it works fine. I just jumped into python 3.</p>
  
  <p>I am trying to fix this for 2 hours already, all solutions here do not work for me, probably I am missing something. As far as I understand somewhere I need simply to add <code>.encode("utf-8")</code> But I tryed already to put this everywhere. I thought it must be either the <code>salt</code> or the <code>x</code> in <code>h.update(x)</code></p>
  
  <p>I get the <code>Unicode Objects must be encoded before hashing</code> in these lines:</p>
  
  <p><a href="https://i.stack.imgur.com/iNqWo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/iNqWo.png" alt="enter image description here"></a></p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I found the line where something happens if I encode, but it results in an other error.</p>
  
  <pre><code>u = _pseudorandom(''.join(map(chr, u)).encode("utf-8"))
  </code></pre>
  
  <p>results in:</p>
  
  <p><a href="https://i.stack.imgur.com/1WoRs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1WoRs.png" alt="enter image description here"></a></p>