Password protection for Python and PHP - php

I am currently building a web/desktop application. The user can create an account online and login either online or via the desktop client.
The client will be built in Python and exported to exe.
I want to encrypt the password before it is sent online as the site has no https connection.
What is the best way to do this so the hashed password will be the same in python and php? Or is their a better way or should I just invest in https?
I have tried using simple hashing but php md5("Hello") will return something different to python's hashlib.md5("Hello").hexdigest()

Forget this idea. Hashing the password on the client, sending the hash to the server and then compare it to the stored hash is equivalent to storing plain passwords in the database, because the hash becomes the password.
Or should I just invest in https?
Yes!

Can you share a code example to reproduce this, along with the two different outputs ?
They should, and do, create the same output.
You should also either use HTTPS or look use a challenge response mechanism ( here's an example that many mail servers use : http://en.wikipedia.org/wiki/CRAM-MD5 )
Encrypting the password has no security effect - anyone can intercept the password and re-use it. The password remains secret, but anyone can still login as if they know it.

Related

Best practices for hashing a password without using SSL

I know this question sounds like it might already be answered but stay with me. I have a website that needs users to sign up and log in. In this process, lets take sign up the user would provide a username and password, the system will check the information and then POST to itself for the PHP script to salt and hash the password before storing it in the database.
Now i thought this was safe, salt and hashing a password is always best practice but recently i thought about how this is happening, the data has to be sent to the server before it can be hashed up and because i don't use SSL the username and password are sent unencrypted, so would i be right in assuming that this information would be sent in plain text?
If so, this isn't good at all. So the only two ways i can see about getting through this is either:
Using SSL and securing the connection between the user and the server and encrypting the data being sent.
Hashing the information before it leaves the user, this could be done using Javascript
I want to implement the second but I'm not sure of how to do this. What would be the best practise for this?
I was thinking before the information is sent a AJAX script will take control of the data and check to see if first the information is what we're looking for and then salt and hash the information.
Are there any security implications on this implementation I have described?
Thanks for your time.
Using SSL and securing the connection between the user and the server and encrypting the data being sent.
Yes, do this.
Hashing the information before it leaves the user, this could be done using Javascript
This will not secure the data. Instead, it would effectively change the secret data to be sent to the server to the hashed version of the password. That would still be sent as plain text and attackers could sniff it and know exactly what to send.
You might be interested in the Secure Remote Password protocol.

PHP - Storing password for external service securely?

I'm currently planning the development of a PHP application that shall require user passwords for external services to be stored so that they can be logged into simultaneously when the user logs into my application.
I shall need to store passwords in a secure, i.e. not plain text, and not base64 encoded but that shall also need to be accessible as plain text by the application, one way or another.
I've only been able to think of something like the following:
When a user adds their credentials for the external service to their account, they re-enter their password for my application and that (in an encrypted form) is used to 'encrypt' the password for the external service somehow, but in a way that makes it accessible still.
Does anyone have any thoughts on if this is possible, or a potential solution?
Thanks
Also: it's worth noting that it will be an SSL connection that the data is sent over.
Out of curiosity: Say for example; Google Mail, you can add email accounts to your Google Mail account so that all of them are checked. Does anyone have any thoughts on how Google store the passwords for the accounts you add?
The problem with this in general, is if your system is every compromised, the attacker can get all the passwords for all the systems, because they are encrypted and not hashed. There is no way around this, since you want to be able to get the plain-text passwords.
If you must do this, you can use something well trusted like OpenSSL to encrypt the passwords.
From a securities stand point, you really should never store a password anywhere. I would have the user enter their password md5 their password and store that. So when he authenticates its authenticated vs the md5. As for the externals. You could take the external password and XOR the external password with the stored md5. That way you could undo it to pass it to the external source. Or the better way would be to ask for the password every time for the externals. This is a choice of risk vs convenience.
Well, you may encrypt the passwords by user's own password (not storing it anywhere), and just ask for it every time the communication is being made, this way the passwords are probably safe.
GAH... I wish everyone would just standardise on keys:
<?php
$connection = ssh2_connect('shell.example.com', 22, array('hostkey'=>'ssh-rsa'));
$sth = $dbh->prepare('select keyLoc from auth where username = :user');
$sth->bind_param('user', 'username');
$key = $sth->fetch(PDO::FETCH_ASSOC);
if (ssh2_auth_pubkey_file($connection, 'username',
$key,
'/home/username/.ssh/id_rsa', 'secret')) {
echo "Public Key Authentication Successful\n";
} else {
die('Public Key Authentication Failed');
}
?>
It would make life so much easier. Just copy your public key everywhere and keep your private key on you.
What you should do instead is to use Oauth - safer and also much more user friendly when it's implemented correctly.
Zend oauht client
You can use php mcrypt, see relevant question here. Or if you prefer to encrypt/decrypt server side mySQL has a AES encrypt function.
You might use something like PKIF (specifically PKIFCRYPTO) and NSS or MS-CAPI. It's not for the faint of heart, but you'll want to demonstrate a certain degree of competence to the users who decide to trust you with their credentials.

Log into Webserver from Iphone App?

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

Encryption within native PHP and PERL

I am looking for a way to insert encrypted passwords into a database (MySQL) that I can decrypt later. I've done research and I've came to the conclusion that bcrypt would be the more secure way to store passwords, but then I can't get them back, and it's important that I know their passwords in case I need to login to their system (I don't want to rely on IP authentication).
http://php.net/manual/es/function.mcrypt-cbc.php has some good examples of using a library for encryption on both PHP and PERL, but PERL requires an additional library and PHP needs to be a certain version.
I am looking for a solution that has ability to run on PERL and PHP natively (no additional libraries) with versions that atleast a year old. No PHP 5.3 functions or anything of the like.
The system only has 100 or so users, so there isn't a huge risk of someone even getting access to the database, but just incase I want some kind of protection. If need be, I would be OK with having to add a library to PERL, but I can't really be picky with a PHP library or require PHP version higher than 5.0
If you're using MySQL you may want to look into using mysql functions such AES_ENCRYPT/AES_DECRYPT:
http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html
Using a standard hashing function (e.g. one of the sha versions) does mean that you can't get the password back but it doesn't mean you can't log in to their system.
Just update the password hash in the database with a known one (e.g. update user set password = sha1('password') etc), log in, then update the password back to the old hash. You're in, and their password is back to how it was.
If you're encrypting and decrypting, then the keys will need to be on the server; if you're compromised, the attacker will have access to the keys as well, so you might as well leave the passwords unencrypted if you're not going to hash them.
Just hash the passwords using SHA256 or SHA512. It should be enough. Now, you said you want to know their passwords so you can login into their account. You, as the administrator, should have the ability to login as the user without knowing their passwords.
If you need to login as the user then I am guessing you need to change something? Well, an administrator should be able to change users data without having to be logged in as them...
So I can only say fix your system.

Sending passwords over the web

So I'm working on a mobile platform application that I'd like to have users authenticate over the web. I was wondering the best way to do security. The user is sending a password for HTTP to a php server wich authenticates against a mysql database on the same server. Obviously I don't want to send the password in plain text over the internet, but I also don't want to do 2 SHA hashes.
This is what the server looks like (in pseudocode)
$pass = $_POST['pass'];
if ((get PASSWORD where USERNAME = USERNAME) == SHA($pass)) return PASS;
This is pretty standard and I don't think there's any other way to do this. But I was wondering how I should prepare the data before sending it over the internet.
If you want security, YOU. MUST. USE. HTTPS. With a proper, non-self-signed certificate. Whatever you do, identities that are authenticated in unencrypted communication will be trivial to steal. (Never mind the password, the attacker can simply steal the session cookie that is provided with every request.)
Hashing is worthless in itself, you must salt it. (This is not really related to authentication - it is a second layer of defense for the case when someone steals your database. Which will probably happen sooner or later if you become a promising target.) Use bcrypt with long random per-user salt, sha* is insecure because it is too fast.
Use methods that are already in use by large, security-aware projects. Those methods have, to some degree, withstood the test of time. There are challange-response based methods that avoid sending the password in any form, but crypto is hard, and it is very easy to implement secure algorithms in an insecure way. Use a good security framework (e.g. PHPass), don't rely on code that is not widely in use.
You could use SSL if your client app supports it.
For regular non-critical system most websites send the password in plain text over the Internet during a http post request. The password is then server side encoded by SHA1/MD5 and checked against the value in the database.
You can also use https basic authentication, this will encode the password with a simple algorithm. But although it does not send the password in plain text, the encoding is so simple that it’s very (very!) easy to crack. But by using basic authentication, you cannot use a regular login form, you will need to do with the browsers support for basic authentication (not very user friendly!).
If you need more security most websites just install a server side SSL certificate that you buy at an ISP (for example godaddy). This will make it possible to access you’re login script over an SSL encrypted connection. This solution is considered secure (as long as the password is not easy to guess or stolen).
An other interesting, but uncommon approach, is to do the SHA1 encoding in JavaScript before doing a (Ajax) post request to the server (JS sha-1 example). In theory, this could deliver quite reasonable security…
And if this all is still not enough you could consider installing client certificates or a response-challenge system with a calculator or SMS.
As Pekka pointed out, SSL is your best option.
As an alternative, using SHA in JavaScript is pretty easy, fast, and it's already been written. Here's an example and here's a library: crypto.js

Categories