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.
Related
I'm creating a website which encodes user's data (e.g. username, e-mail, phone number...) so that their data is safe.
To prevent data from getting to the public I'm encoding it using SHA1 before storing it in the database. I'm handling the requests using PHP.
When a form is submitted and data is sent, can the data be leaked or intercepted? by the NSA or an attacker for example.
If so, I'm thinking about encoding the data using JavaScript right before the form is submitted. Would that work?
I know I shouldn't be answering this as it is off topic but there are things that must be cleared here:
"Encoding" data
In your first paragraph, you said I am encoding the entered data, I don't know what you mean exactly by that.
If you mean encryption, I'm not sure how are you encrypting e-mails/username if you use them for authentication.
But generally speaking, encrypting data is a good thing as long as you are using a good cipher with a strong securely stored key, check Where to store a server-side encryption key?.
You also said using sha1 before storing it in the database. This is also unclear, are you hashing all data with sha1? if so. how do you "unhash" the data when you need it.
I suppose you are hashing passwords, but sha1 and md5 (two common algorithms) are not suitable for passwords (or as #Peter said: unsuitable for anything security related).
To hash passwords, you need to use the right algorithms for that such as bcrypt, scrypt or argon.
In PHP, the best way to hash a password is by using the native built-in functions. password_hash() for hashing and password_verify() for verifying the hash.
These functions are available in PHP 5.5 or newer, if you use an older version - consider updating - you can use this compatibility library by ircmaxell.
Data "leakage"
In the 2nd paragraph, you talked about data submitted in a form being "leaked", I suppose you mean intercepted a.k.a. Man-In-The-Middle attack -MITM for short-.
To protect data from MITM attacks, you need to use HTTPS instead of the insecure HTTP.
HTTPS encrypts the data sent between your server and the client (browser/user) which will prevent anyone from intercepting the data.
Usually to get HTTPS you have to pay, but now there is a free Certificate Authority -CA for short- called Let's Encrypt that provides free certificates.
Encrypting data using JavaScript
You talked about encrypting data using JavaScript before submitting the form.
That wouldn't work simply because, when the client connects to your normal HTTP website, the HTML/JavaScript is in plain-text and can be changed, the attacker can simply intercept your JavaScript code (the one that will encrypt the data) and change it to whatever he wants.
The only solution you should consider is getting an SSL certificate for your website.
NSA thing
I assume that you are talking about the surveillance done by the agency, there are two things here:
MITM attack Which I already covered above, use HTTPS.
Accessing data on your server. If the NSA is somehow interested in your data, and your server is in a place where they have jurisdiction over, they can simply access the unencrypted data in your server.
Wrong terms you use
I see that you are miss-using the terms, encoding is not what you think.
Encoding is just transforming the data into a specific format (say JSON for example).
Encryption is when you take data and transform it to an unreadable format using an algorithm and a secret key, encryption protects the data from unauthorized access, encrypted data can be decrypted to its original state.
Hashing is generating a value (called a hash) from given data using a one-way function.
Which means, given a hash you can't theoretically get the original value back.
This is just a general answer to your question and not an ultimate security guideline (I'm not a security expert!)
References
How to use bcrypt in PHP
Man-in-the-middle attack
Why is SHA1 considered less secure than often necessary?
HTTPS
Hash function
bcrypt
A simple answer to your question "Is data submitted in a form secure?" is Yes and No. It depends on how you submit your data. If you are using a cleartext protocol such as HTTP, then it is insecure. Because the data is transmitted in a cleartext and an attacker can sniff and read the data. However, if you are submitting the data over HTTPS, then yes, your data is securely submitted.
Now comes the data storage part. It is recommended to hash the password using a strong hashing algorithm and salt before storing it in database. You need not hash/encode data such as email id or username. This can be stored as plaintext.
So, in short, if you are submitting the data over SSL and hashing the password before storing, you are encrypting the data during the transmission and securely storing it in the DB. This is industry standard and many companies including the top security companies follow this.
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
Currently I am connecting my login system with RSA class (class that is implementation of RSA algorithm in PHP). I've read some info about this algorithm, although I have got some doubts to it and hope that someone can clarify them.
RSA is operating on two keys - public and private, both are generated using algorithm. Are those keys only generated once and then included into site code (one on admin and one on user site)?
The main idea of implementing it is to put on site let say login.php with login form into code a public key and when login and password are sent for verification encrypt them with public key. On server side this message will be decrypted using private key and checked if info are correct and send back true/false info. Can you tell me is it safe and correct use of it?
Just use HTTPS instead of getting lost in the implementation of these algorithms. I bet a Javascript implementation would signify a large overhead on client-side. When you want to encrypt your pockets, let the Transport Layer or the Application Layer (HTTPS) to do it - it's tested, it's fast, it's working, it takes a few minutes to setup.
Please don't implement this - use HTTPS instead. What you proposed is not secure at all. The form data will not be secure if you encrypt it on the client side using JavaScript. JavaScript is not good for encryption.
The basic rule is anything executing on the client is malicious. To run an encryption on the client is a really bad idea.
Again - use HTTPS or don't do it.
If you want the transmission to be secure you can't use a server-side scripting language for it. The encryption and decryption will first occur when the cleartext password has reached the server, giving an listener good time to intercept. You could use a javascript implementation of RSA to encrypt the password client-side and then php on the server-side to decrypt it.
You would have your public key for encrypting and the private key on the server for decrypting.
I am creating a program that communicates with a PHP script on a web server and to do so I need to be able to pass parameters from the program to the PHP script.
Now here is my question. At some point the user name and password needs to be passed to the script. Now this is not done in a way that is apparent to users (such as in an address bar) but I know with a little sniffing around someone that really wanted to could figure it out. So while my script is safe from injection, obviously variable tampering is an issue here.
This is an idea I have come up with so please help me wrap my head around it and see if this would work the way I THINK it will.
My thought was to encrypt the user password (or another unique key) variables on the client side before sending so you get a url like (obviously just made up) mypage.php?un=Oa348uty8&ps=op986hGTfreu Then when it gets to the PHP script decrypt it and encrypt it again with a different salt.
So when it leaves the application it would be encrypted but not the correct way, and then when it hits the PHP script server side decrypt it and re-encrypt it with the correct salt so it would correctly match the stored encrypted password.
This way, they user would not know what the encrypted version of their password is supposed to look like so without that they would not be able to tamper with the URL and try to insert fake values.
To put it in a nutshell, you are thinking of this:
On server side you have:
a database, with login/password matches.
a script that take 2 parameters (password and username) and check in the database if the couple exists
Your problem:
When your local application call the php script on server side, the 2 parameters are given in plain text. And you want to avoid tampering ( if your script are safe against injection i only see tampering used to bruteforce the auth <= keep in mind that i will keep this assumption in the whole post)
Your solution:
On client side, encrypt the 2 parameters
On server side, add a salt in your script to salt
Then decrypt the 2 parameters and encrypt with a salt
What I think:
This will not solve the tampering issue, someone can still forge requests.
The first encryption is useless because someone can retreive the key used by your client.
The second encryption is not safe enought because you use the same salt for all you users.
What I suggest:
Accept that tampering can't be avoided if you don't use a secure protocol like HTTPS (can either use SSL or TLS).
If you want an acceptable security without HTTPS the following is what i would implement:
A token system that you will check in order to see if the user can perform the login operation
A username that would not be encrypted
The password sha1 hashed stored in database
On client side, you call the script and provide the username as non encrypted and your password as a sha1 hash, rehashed with a random salt (sha1(sha1(pass)+salt) (the salt is stored in the user session on server side)
The script would then compared the provided hash with db password hash rehashed with session salt
The improvement is that the attacker must try to brute force two sha1 passwords consecutivaly and must provide a valid token to perform the login action. Plus if you use as salt a string using hex char of a variable even length, it will make the job harder for the attacker to recognised that the value bruteforced by the second hash is a sha1 hash, and even if he know it's an sha1 he will have to test multiple case to try to find the right portion of the value that correspond to the hash.
Because of variable salt, a same password won't be the same if hashed:
Imagine the attacker sniffed a hash and know which password was used then sniff another hash that was made with the same password as the other, the attacker won't be able to know that the 2 password where the same( a little overkill but still usefull).
It is safer to store the password as hashed value, because if the attacker manage to dump your user table, he won't be able to use the passwords right away, he would have to bruteforce each of then.
Finally sha1 hash are safer than md5 (i tell you that because you used the md5 tag in your post)
The downside of this method is that passwords can't be reversed, so you won't be able to given them back to your users if they lost it. You will have to make them set a new one.
An hardcore way (still without using HTTPS), would be to encrypt your password and username with a strong cypher (like AES or 3DES) and use a secure key echange algorythm (like the Diffie Hellman one) to exchange a random shared key.
This method won't block tampering, but will screw the attacker, because he won't be able to decrypt the value (assuming he only is sniffing the network). The key is random and never hardcoded in any of your application, so even if someone reverse your client, he won't be able to retreive a key.
I would still recommend to store your password value has hash.
An extreme way would be to merge the 2 methods but would be completly overkill.
Hope this will give you ideas
The problem with your approach isn't whether you are using encrpyted passwords and usernames in the URL or not. If the user authenticates by sending the encrpyted strings to you, then I as an attacker can still sniff out those hashes, pass them to your application and authenticate. This is unless then, that you do some public key/private key exchange before hand, but that is just reimplementing HTTPS, so you might as well just use HTTPS.
What you should do is to send the request using POST over HTTPS.
POST: So that the authentication details will not be in the URL and show up in logs and referrer URLs.
HTTPS so that the content of the whole request is fully encrypted and can only be decrypted by the client application and the server side.
encryption with Javascript from client to server only prevent from non SSL posting fails.
I think you must use sessions instead of this type encryption .
Update:
You could add your own secret key in both scripts.
i wonder if there's a secure way to deliver a password with an URL (like ?p=mypassword)
how can i encrypt and decrypt such a password so it's secure.
i guess md5 is not working in my case because the password must still be readable. It's an FTP passwort which gets passes along to the ftp_connect. i think md5 doesn't work in this case because i have to query if a string matches the md5 hash. however i can't do that in my case.
any ideas?
Erm: Send via POST + SSL
SSL ensures that the password can not easily be read by third parties while in transit. Sending it via POST simply sends the variable to the server outside the URL and keeps it out of the server logs (hopefully). This will do an alright job hiding it from browser history or people sniffing HTTP.
But then, doesn't ftp_login() send this plaintext when using ftp_connect() making a mockery of the SSL in HTTP? Make sure you use ftp_ssl_connect() to your server afterwards. See the ftp_ssl_connect() PHP manual entry
If your site accepts an encrypted password in the query string, that encrypted string - though unreadable - is functionally no different than the password itself.
If my password to enter the CIA is "password", but they'll let me in if I say "5f4dcc3b5aa765d61d8327deb882cf99", both strings function as my password and both need to be protected.
Instead of using a one way hash (MD5, SHA1). I think you need an encrypt-decrypt function. Take a look at this http://www.php.net/manual/en/function.mcrypt-encrypt.php.
The above example, you can encrypt using the key and pass the password in the URL. Once the password is received by PHP, you can then decrypt the password and use it to connect FTP. The only limitation is that the key will have to be available on the PHP server and wherever you generate the URL. There are also limits on the size of the string but I think you will be within those limits generally.