title: Decrypting AES and HMAC with PyCrypto
body: <p>Having a bit of trouble getting a AES cipher text to decrypt. </p>
  
  <p>In this particular scenario, I am encrypting data on the client side with Crypto-JS and decrypting it back on a python server with PyCrypto.</p>
  
  <p>encrypt.js:</p>
  
  <pre><code>  var password = 'BJhtfRjKnTDTtPXUBnErKDxfkiMCOLyP';
    var data = 'mytext';
  
    var masterKey = CryptoJS.SHA256(password).toString();
  
    // Derive keys for AES and HMAC
    var length = masterKey.toString().length / 2
    var encryptionKey = masterKey.substr(0, length);
    var hmacKey = masterKey.substr(length);
  
    var iv = CryptoJS.lib.WordArray.random(64/8);
  
    var encrypted = CryptoJS.AES.encrypt(
      data,
      encryptionKey,
      {
        iv: iv,
        mode: CryptoJS.mode.CFB
      }
    );
  
    var concat = iv + encrypted;
  
    // Calculate HMAC using iv and cipher text
    var hash = CryptoJS.HmacSHA256(concat, hmacKey);
  
    // Put it all together
    var registrationKey = iv + encrypted + hash;
  
    // Encode in Base64
    var basemessage = btoa(registrationKey);
  </code></pre>
  
  <p>decrypt.py:</p>
  
  <pre><code>class AESCipher:
      def __init__(self, key):
          key_hash = SHA256.new(key).hexdigest()
          # Derive keys
          encryption_key = key_hash[:len(key_hash)/2]
          self.key = encryption_key            
          self.hmac_key = key_hash[len(key_hash)/2:]
  
  
      def verify_hmac(self, input_cipher, hmac_key):
          # Calculate hash using inputted key
          new_hash = HMAC.new(hmac_key, digestmod=SHA256)
          new_hash.update(input_cipher)
          digest = new_hash.hexdigest()
  
          # Calculate hash using derived key from local password
          local_hash = HMAC.new(self.hmac_key, digestmod=SHA256)
          local_hash.update(input_cipher)
          local_digest = local_hash.hexdigest()
  
          return True if digest == local_digest else False
  
  
      def decrypt(self, enc):
          enc = base64.b64decode(enc)
          iv = enc[:16]
          hmac = enc[60:]
          cipher_text = enc[16:60]
  
          # Verify HMAC using concatenation of iv + cipher like in js
          verified_hmac = self.verify_hmac((iv+cipher_text), self.hmac_key)
  
          if verified_hmac:
              cipher = AES.new(self.key, AES.MODE_CFB, iv)
              return cipher.decrypt(cipher_text)
  
  
  password = 'BJhtfRjKnTDTtPXUBnErKDxfkiMCOLyP'
  
  input = 'long base64 registrationKey...'
  
  cipher = AESCipher(password)
  decrypted = cipher.decrypt(input)
  </code></pre>
  
  <p>I'm successful in re-calculating the HMAC but when I try and then decrypt the cipher I get something that seems encrypted with �'s in the result.</p>
  
  <p>I was getting errors about input length of cipher text but when I switched to CFB mode that fixed it so I don't think it's a padding issue.</p>