I am trying to make a HTTPS call to the Paypal PayflowPro gateway API. I need to pass the credentials along when I make the call. What is the best way for me to encrypt / decrypt the password for our account. I don't wanna hard code our password into my PHP script.
I have searched for things similar to this thread's title but I can't seem to come up with a concrete answer.
If you are worried the password will be sniffable, you can stop worrying, the SSL connection encrypts the sent data for you.
If you want to store the credentials in a configuration file, I can understand your concern. You can use some of the encryption methods to store the credentials in a encrypted form on disk and decrypt them before sending them to the paypal service.
If I'm correct you could use the MCrypt library in PHP to get this done.
The possible cyphers are available here http://www.php.net/manual/en/mcrypt.ciphers.php
Just make sure you don't use a (non-decryptable) hash algorithm like MD5 or SHA1, and remember the seed (key) you use to encrypt the data.
Related
I found many questions/answers here and many articles in other websites but I have still a few questions which I need to answer before I can start and I just can't find answers for them. I want to create restful api for mobile apps (and for some frontend).
I choose Basic Authentication via HTTPS because I guess it's enough for now and it looks easy to implement. So I should have username and hashed password saved in dabatase right? Then when user write username and password in app I hashed password and both encrypt by Base64 and add to HTTP header right? How can I decrypt this and check with database on server-side? How it would change with salt?
And after I check username and password with previous call then how can I save this session? Should I create some session-id/token (random string) and save it to column in users table and send it back to mobile app and then using it for other calls (with some timestamp for expiration)? Could it be via HTTP (no secure)? Like web.com/api?token=ASsF234Silkj&data=... Or I must always use HTTPS after authentication?
How will it change when I use some API key (private) in all apps which would use this API? I know I can hide key and don't send it via requests (use it just for encryption) but what if someone try to read .apk and get API key?
First off, base64 is not encryption
While it is possible to integrate basic http authentication with sessions it is not a trivial task. And it's very easy to end up with something which is insecure (especially judging from the level of skill evidenced in your question).
You seem to have planned out most of what you want to acheive - but you've got most of it wrong already.
Whether you should continue to use HTTPS after authentication depends if your service has any intrinsic value.
Similarly how you implement surrogate authentication tokens (including API keys) depeds on the security model. Stick to using HTTPS everywhere and you should not have to worry about changing / encrypting the API key.
So I should have username and hashed password saved in database right?
Yes, you should hash it, don't use MD5 or SHA1, they are now no more secured. Use SHA2 or SHA3.
Then when user write username and password in app I hashed password and both encrypt by Base64 and add to HTTP header right?
Base64 is not hash function, you can get original content from base64, it's just a encoding way.. Yes you have to put credentials to HTTP header. While sending user name and password (hash or plain), use HTTPS connection. Sending hash in HTTP connection is vulnerable to replay attack.
How can I decrypt this and check with database on server-side? How it would change with salt?
If you send Hash , you cannot decrypt it (that the sole purpose of Hash). I would recommend you following:
1) send user name and password to server via https
2) create hash at server and check with the existing hash in database.
And after I check username and password with previous call then how can I save this session?
depends on which langauge you are using
Should I create some session-id/token (random string) and save it to column in users table and send it back to mobile app and then using it for other calls (with some timestamp for expiration)? Could it be via HTTP (no secure)?
you can do that but use HTTPS, and do not use time stamp, it is very unsecure. Rather generate long random string
How will it change when I use some API key (private) in all apps which would use this API?
???
I know I can hide key and don't send it via requests (use it just for encryption) but what if someone try to read .apk and get API key?
Do not put key in APK, generate it locally if it is private key (if i got what you mean)
I need to send sensitive data through a url like following.
http://www.mydomain.com/handlingfile.php?username="abc"&password="pass"&BankAccount="0983479"
What is the best way to encrypt the parameter values in order to have a secure communication?
Do not fuss around with browser encryption, switch to https for save transport. That is what is was 'invented' for. For a few dollars a year you can buy a certificate. It gives your users a 'safe environment' feeling when there is a 'lock' icon displayed in the browser.
Do not send your username and password in the url, but use a post action in your form.
Consider using oAuth service, so users login with facebook or google account. You do not need to store the credentials at al, just the token you receive from oAuth.
Use SSL, its the right way of encrypting data between client and server requests.
The other way might be to store the encrypted passwords and bankaccount number in database using One way encryption like MD5 or SHA1, and pass encrypted passwords and bank account in URL with same encryption and match them from database.
But again the best is using SSL
use
urlencode
and
rawurldecode
You can also encrypt data using javascript with your own algorithm. But none of these secure
I am using PHP/CodeIgniter and Tank_Auth library for authentication both on site.com and via the API, and a very basic REST API from Phil Sturgeon.
Right now when a user fills in username/password on Site1. It makes an API call like so:
http://site2.com/api/index/authenticate?username=jdoe&password=123456
On Site2.com: index/authenticate uses tank_auth library to compare username/password to what is stored in the database.
My Question:
Is there a standard to encrypt the password during submission and then decrypt on the other side? Or would an SSL certificate be sufficient?
how about creating a hash of the 2 with some "salt", pass that in the query string, then make sure it matches by running the same hash on the 2nd server.
http://site2.com/api/index/authenticate?username=jdoe&password=123456&cs=fds34wsef3ewtdfgw54ty43wg
make sure you keep the salt secret... not too sure about passing this in GET, especially passwords - maybe you could pass a separate id hash instead of the password. Definitely use POST though, and ideally SSL. The more you can obfuscate,encrypt the more secure this will be
I have a server with mysql information stored on it. Now i need my Iphone application to be able to log in to a account and update information stored in the the database. So i was wondering, what would be the best way to go about this?
Shall i just use POST to send data to a PHP script and then echo a response for wether the user can login or not(The username and password match) ?
It's just this seems unsecure, also do i need to create some kind of session once the log in stage has been completed?
I have never done this before, so would be really grateful of any help!
Thanks very much
You described the common way to do it. You need some sort of a webserivce you can "talk" with. It's done in the way you post the data to the webserivce, the webserivce (e.g. written in PHP) opens a connection to the database and returns wether the request/login was successful.
If you just send the password in clear text, than it's unsecure you are right. I use two things to make the communication more secure.
SSL: If possible make a secure connections. But it's possible that you do not have the option to connect through ssl.
Password hashing: You can at least hash the password. In a normal case the username is public in an application, but the password isn't. A hashing function is function that returns a string that looks a little bit random to humans. Hash functions are one way functions. There's no way to go back to the original string (if you don't have a few super computers and a few hundred years of time). So once you retrieved a hashed password within your webservice, just hash the password in the database too and compare them. A string always returns the same hash if you use the same hash function. Common hash functions are: MD5 or the SHA familiy
I hope my answer helps you any further. Perhaps my approach is not the most secure, but until know no one told me anything better. ;-)
For phone apps, desktop app and some web apps this is a common issue.
Sandro Meier (above) said correctly that if you have SSL access then this is best way to send via a HTTP POST a username and password so anyone else on the network cannot sniff these details.
If you cannot use HTTPS, then I would recommend from your iPhone app.
1. post username + password to the PHP from the iPhone.
2. ON the server in PHP code, check these details, if correct generate some random token eg (KHnkjhasldjfoi&*) you can do this by using the MD5 hash function in PHP.
3. Save this hash in the db so you know which user you sent it back to.
4. Now for all other requests from the app to the PHP include this token with the request (in PHP you will need to check this token and if it is valid, then fetch or update data).
5. This way if someone is trying to sniff the connection they dont have access to the users password, they can only steal the token.
If you want to be 99% secure you need to use a HTTPS connection (but HTTPS can be faked, I wrote about this in Computer World).
The pervious person mentioned using a MD5 hash to send the username password, but this also can be hacked (a user could download you app, find the salt to the MD5 hash and that way they could still steal any password). I think the W3C said that they do not recommend encrypting web forms and password pages as it gives a false sense of security because pretty much anything can be decrypted (I think a Quantum computer can even decrypt HTTPs), they recommend using HTTPs as it provides the most security for sending sensitive data.
W3C Passwords in the clear.
http://www.w3.org/2001/tag/doc/passwordsInTheClear-52
Basically, I have an ajax form that carries login information, is there any way I can encrypt the password before it sends in ajax then decrypt it in php?
Or any other ways I should look at it?
Many thanks :)
There is no reason to do any encryption in JavaScript or PHP as the appropriate solution is to use SSL (HTTPS). Nowadays you can even get certificates which are trusted in all browsers for free so there's no reason for not using SSL.
If you cannot use SSL for some reason, you could get a JavaScript implementation of RSA so you can encrypt it locally but only your server is able to decrypt it again.
You could use RC4, since I know theres an implementation of it in PHP and Javascript. However, with any sort of encryption, you'd have to leave the key client side (so it can encrypt it), which means that anyone who has access to your page can get the key and decrypt it (thus defeating the point).
You might be better off either hashing it client-side (and then matching the hashes in PHP, if you don't need to know the password), or using Public-Private key encryption (like RSA), so that clients can encrypt, but not decrypt it.
For hashing, look at hash() and sha1 for Javascript.
And for RSA, check out this blog post http://www.sematopia.com/2008/10/rsa-encrypting-in-javascript-and-decrypting-in-php/
Use an SSL certificate and send the login over HTTPS from your AJAX form.
You can't in a secure manner. you should use https
You can do md5(password) in both JS and PHP, and then compare the encrypted passwords.
As username is not encrypted, you can use it to take the password from DB in PHP, and then encrypt it.
Best way to do that is:
generate a uniqid, save it in $_SESSION['crypt_key'], and send it as a hidden input on the ajax form;
encrypt in JS using md5(crypt_key + password) before sending it;
encrypt in PHP using md5($_SESSION['crypt_key'] . $password) and compare them. This way, every request will transfer an unpredictable crypted password.