2
votes

I'm trying to pass an encrypted query string to another URL.

The following code gives me this error:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u04b7' in position 7: ordinal not in range(128)

The encryption module is PyCrypto

Running Python 2.5.2 on App Engine

PAGE A

    import Crypto
    from Crypto.Cipher import ARC4

    obj=ARC4.new('stackoverflow')
    msg = 'This is my secret msg'
    encrypted = obj.encrypt(msg);

    self.redirect('/pageb?' + urllib.urlencode({'q': encrypted}))

PAGE B

    import Crypto
    from Crypto.Cipher import ARC4

    encrypted = self.request.get('q')
    obj=ARC4.new('stackoverflow')
    decrypted = obj.decrypt(encrypted)

    get_data = cgi.parse_qs(decrypted)

    self.response.out.write(decrypted)
    self.response.out.write(pprint.pprint(get_data))

Traceback

Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\_webapp25.py", line 701, in __call__
    handler.get(*groups)
  File "C:\Program Files\Google\google_appengine\demos\guestbook\guestbook.py", line 47, in get
    decrypted = obj.decrypt(encrypted)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u04b7' in position 7: ordinal not in range(128)
2
This appears to be a statement of fact, with minimum collateral. Try asking a question, supported by useful information, like a traceback. - John Machin
@JohnMachin Thanks, I've updated the post. - Chad
The information is there now, but the question is still implied at best. - Karl Knechtel
Why are you redirecting to another URL in your own application, trying to encrypt things between requests, instead of just calling the required internal API bits in your request or storing the sensitive information server-side with session control? This seems needlessly complex. - Wooble

2 Answers

6
votes

General guidelines: add base64 encoding/decoding step in your encrypted stuff.

import base64

base64_encrypted_message = base64.b64encode(encrypted_message)
// send your message via POST as GET can be seen on system logs

encrypted_message = base64.b64decode(base64_encrypted_message)
// decrypt your message

For the other error, try reading up on unicode & utf-8 encoding of non-ascii characters. You need this step before passing it to your de/encrypt function.

1
votes

All that can be deduced from the information available is that something is expecting a bytestring but you have fed it a unicode object containing the Unicode character U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER ... this is of course not encodable in ASCII (the default encoding), hence the error message.

Best possible answer so far: Don't do that.

Update 1: You still haven't asked a question. Nonetheless:

So "something" is some crypto gadget's decrypt method. That surely needs a str object. What does print repr(encrypted) tell you? If it looks like random rubbish (as encrypted stuff should), then somehow it has been converted from a str object to a unicode object. You need to back-track to see how this is happening. If encrypted looks like meaningful text, then your encryption process is broken.

Step 1: Start with some known plaintext, encrypt it, and decrypt it again in a simple script outside the GAE apparatus. Use print repr() at each stage so that you have reasonable expectations for the next step.

Step 2: Repeat step 1 using GAE, inspecting the type and contents of each piece of data.

Update 2 It appears that you have a urlencode in page A, but no corresponding urldecode in page B; is this (part of) the problem?