I’m wondering if anyone out there knows the method that PayPal hashes their passwords containted within the IPN system.
Sure they tell me it’s hashed but they don’t say what to do about it. I need it to activate my subscriptions. If anyone could point me int he right direction, I’d be eternally greatful!
I don’t have an answer for you, but it seems that your best bet would be continuing to go straight to the source - ask PayPal again. If they don’t give you the info, chances are they don’t want to share it with anyone for whatever reason.
I’m surprised this question isn’t being asked more often! The PayPal docs are HORRIBLE for this!
The answer to your question is that the password hashes for PayPal’s subscription/recurring payments are 13 character unix-style DES hashes (which I think is provided in base64.) In PHP you can use the “crypt” function to produce this hash, and in mysql you can use the des_encrypt function to produce it. That’s not all though. PayPal uses the first 2 characters from the hash as a salt. I’m not sure how they do this, since it’s kind of a “chicken and the egg” issue, but here’s an example/proof:
PHP:
echo “The actual password for a subscription, provided by PayPal: ore9gatexE<br>”;
echo “The hash that PayPal provided me with: xEDmQW52fNRIU<br>”;
echo "Your hash: " . crypt(“ore9gate”, “xE”);
At this point my problem is that MySQL’s des_encrypt() function (which works just like ‘crypt’ above for what we’re doing,) outputs a binary hash instead of a string. This means I can’t use it to compare hashes with the ones PayPal provides, unless I come up with my own conversion method!
I had to experiment and HUNT for all of this information… Now, I think I either need to use a proprietary base64 mysql function to convert the binary hash to a string, or I need the opposite, to store the PayPal hashes as binary in my database in the first place.
Hopefully this will save many others a lot of grief!
Anyone - please let me know if you have any suggestions for the conversion, or anything else (like getting the password from a login page to the server without sending it in plain text or relying totally on ssl – since the first two characters from the hash are required to make the hash (which is so weird,) the matter or a login page is somewhat complicated.) I would like to have been able to just hash login passwords in javascript, and then send that hash over the line to be compared, rather than sending a plaintext password. I’ll use SSL if I have to, but still…)
Those are the only two options available to you for sending anything from the browser to the server. If you don’t use SSL then whatever you send no matter what encryption or hashing you apply is the equivalent of plain text since anyone wanting to bypass the page need simply send the same value as your page sends - they don’t need to know the original value that was ‘encrypted’ by the page.
Worse yet, if you use JavaScript to create the hash (and that is the only option) then you still need to cater for those without JavaScript and so you still need to be able to accept the plain text version as well. The end result is that you end up with two text strings that are equivalent to one another on the server end and anyone sending either one will be able to log in.
The only way of encrypting anything on the client so that it can’t be intercepted and read on the way to the server is using SSL.
Thanks for the input Stephen. Good point. Hmm… still trying to figure out how to convert the string hash into binary or vice-versa… It doesn’t look like the string version is base64 at least. Aside from that, I’m not sure yet. When I test des_encrypt and use php’s base64_decode on the result, it’s not even close to the hash paypal provides…
Stalwart, if you want to use MySQL for the encryption running on Linux, you can simply use the command SELECT ENCRYPT(‘password’, ‘salt’). This will use the crypt() call on the system.
I am trying to resolve the Paypal hash issue in Java, using a JBoss login module. It looks like JBoss is not supporting DES encryption out of the box. Maybe this is because the DES algorithm is part of the Cipher() class instead of the MessageDigest() class. But it seems that I could create my own Java implementation of the algorithm and create a custom login module in JBoss that would use the hash.