can't decode encrypted string in python from messagepack (Ruby openssl)

1.2k views Asked by At

I'm having trouble unencoding some data I get from a socket connection through messagepack, and consequentially unencrypting it. I get the string in from a Ruby on Rails web application in UTF-8 and use messagepack to bundle it all up and send it over to a python service using sockets. The other data comes across fine: strings, numbers, arrays etc. But my encrypted password is wrecked.

https://github.com/msgpack/msgpack/issues/15 this discussion suggested forcing ascii which i did in the rails code as well as here in python. If i force ascii in ruby and do nothing inpython i get junk in the string but i have the correct unencrypted password at the end. If i try to force ascii in my python script i get a decoding error

while 1:
    buf = clientsocket.recv(1024)
    unpacker.feed(buf)
    for obj in unpacker:
        print obj #works great! => ['3', [['really long url', [87987234, 'gobbledyguck of password']]]]
        #key.decrypt(obj[1][0][1][1]) roughly gives "YD3zt�(-�½ï¿½ï¿½=you suck"
        print key.decrypt(obj[1][0][1][1].decode('ascii'))

encryption is done using public/private keys (Crypto.PublicKey RSA in Python, openssl in ruby). i can decrypt and encrypt fine within each script (not sending it over the socket via messagepack)

any thoughts at all?

EDIT:
after some experimentation and a bit of thought, i realized that the fact that password comes out just fine is interesting. the issue is the extra junk at the beginning of the string. I just don't know where it comes from... or whether its safe to truncate it.

2

There are 2 answers

0
Hunter Barrington On BEST ANSWER

The solution ended up being in the fact that the output had the correct unencrypted data with fluff. A couple of quick Google's resulted in me learning that ruby's openssl implementation of RSA public key's by default has PKCS#1 padding turned on... it was hard to find a good python module quickly so the quick and dirty solution was found here

http://kfalck.net/2011/03/07/decoding-pkcs1-padding-in-python

which worked like a charm!

as an alternative (and probably cleaner) solution http://stuvel.eu/files/python-rsa-doc/usage.html looked good.

Looking at the ruby apidock for a way to not use padding was not intuitive http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-public_encrypt

hopefully this helps someone else

1
catbat On

I was recently having issues with what was apparently the network messing up my cipher characters. I tried encoding the cipher in base64 prior to sending it over the network and like magic it worked perfectly.

use:

require 'base64'

cipher = Base64.encode64(cipher)

-send cipher over network-

cipher = Base64.decode64(cipher)