I'm building a simple flask app that allows users to POST data and we return an RSA public key encrypted and base64 encoded string.
Flask App Route looks like the following
def index(eyaml_output=""):
if request.method == 'GET':
return render_template('index.html.j2', eyaml_output=eyaml_output)
elif request.method == 'POST':
input = request.form['eyaml_input']
output = helpers.encrypt(input)
eyaml_output = output
The encrypt function looks like the following
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
import base64
def encrypt(arg):
with open('eyaml_public.key') as public_key_file:
public_key = public_key_file.read()
pubkey = RSA.importKey(public_key)
cipher = PKCS1_OAEP.new(pubkey)
output = base64.b64encode(cipher.encrypt(arg))
return output
This all works well from command line. But when invoked within flask I get the following UnicodeDecodeError
UnicodeDecodeError: 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)
I've tried switching to utf-8 and get a similar error
Edit: I am testing with a python 2.7 virtualenv active. The output itself doesn't seem to matter either. Even when doing an intermediary step this fails with the same Unicode error. The problem occurs on the encrypt portion it seems and not the base64 encoding. Full stack trace below
Traceback (most recent call last):
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-packages/flask/app.py", line
1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-packages/flask/app.py", line
1612, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-packages/flask/app.py", line
1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "app.py", line 13, in index
output = helpers.encrypt(input)
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/helpers.py", line 12, in encrypt
fake_output = base64.b64encode(cipher.encrypt(arg))
File "/Users/bchen/Git/Stoneridge/ansible/eyaml-ansible-
filter/flask/.venv/lib/python2.7/site-
packages/Crypto/Cipher/PKCS1_OAEP.py", line 150, in encrypt
db = lHash + ps + bchr(0x01) + message
UnicodeDecodeError: 'ascii' codec can't decode byte 0xda in position 0:
ordinal not in range(128)
base64.b64encodeproduces a string instead of bytes so you don't have to decode anything. To be on the safe side, always decode your base64 output, e.g.return output.decode("latin-1")