MaxLaumeister/PageCrypt

TypeError: Object type <class 'str'> cannot be passed to C code

GSI opened this issue · 9 comments

GSI commented

Python 3.8.2 (dependencies installed) on Arch Linux 5.6.10:

# python3 encrypt.py somefile somepass
Traceback (most recent call last):
  File "encrypt.py", line 69, in <module>
    main()
  File "encrypt.py", line 49, in main
    encrypted = cipher.encrypt(padded)
  File "/usr/lib/python3.8/site-packages/Crypto/Cipher/_mode_cbc.py", line 178, in encrypt
    c_uint8_ptr(plaintext),
  File "/usr/lib/python3.8/site-packages/Crypto/Util/_raw_api.py", line 144, in c_uint8_ptr
    raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code

What versions are your pbkdf2 and pycrypto python packages?

You can check using pip3 show pbkdf2 and pip3 show pycrypto.

My own working setup is using Python 3.6.9 on Ubuntu, with pbkdf2 1.3 and pycrypto 2.6.1.

GSI commented

What's your full output for pip3 show pycrypto?

I think you may have the "drop-in replacement" PyCryptodome library installed where pycrypto usually goes. PyCryptodome's newest version is 3.9.7 as in your response, but pycrypto's newest version is only 2.6.1!

It's possible that PyCryptodome is not quite 100% compatible with the real deal.

GSI commented

I found changing line 49 in encrypt.py to resolve the issue:

encrypted = cipher.encrypt(padded.encode("utf8"))

Looks good to me. Seems to be working with pycrypto too. I made the change in 84bb9d3.

GSI commented

Wait - it seems to work fine with simple files (ie <html>foo</html>), but with more complex ones the password prompt will just say "Sorry" even though the correct password was entered.

I'll try to get you an unencrypted example file over so we can confirm if the issue is caused by the change at hand or actually unrelated.

Thank you for catching that. Definitely curious to see the file that it fails on!

GSI commented
<!DOCTYPE html>
<html lang="en">
        <head>
                <title>evil pipe |</title>
                <meta name="description" content="evil comma ," />
                <meta property="og:description" content="evil comma ," />
        </head>
        <body>
                will not decode as long as there are special chars in ANY of the above html elements
        </body>
</html>

This is it. Note that decryption does work when using your JS variant at https://www.maxlaumeister.com/pagecrypt/

That test file works fine with pycrypto, even with the new code change. I'm thinking that PyCryptodome maybe returns something different than pycrypto (and thus is incompatible).