I am only a beginner developer and am doing this more to practise my skills.
I am developing a client server application in which the server will host a game and the clients will log in using a username and password.
Firstly:
Once the user enters their id and password, what would be the simplest way to have this sent to the client securely? Do I have to right my own encryption method or are there predetermined protocols that can easily be accessed using the java built in libraries? I have heard of TLS and SSL but am unsure how to make use of these.
Secondly, for security purposes I of course do not want the passwords stored on the server to be saved as plain text. Instead it would be great if instead of storing the password, a hash digest of the password is stored. In a text file for easy comparison. Is there a simple way of producing a hash digest?
Thanks a lot for any help
Encryption:
If you are going to use HTTP protocol for communication, you should use HTTP over SSL.
It provides encryption/decryption to the data transferred between client and server. It
will also help you avoid attacks such as tampering, eavesdropping, man-in-the-middle
attack.
If you have your own protocol for communication, you can always use existing algorithms
like RSA to generate a key pair. When user logs in, let the application encrypt the
password with the public portion of the Server's key, and server will decrypt it using
its own private key.
Hashing:
For hashing you can use SHA-2. (MD5 and SHA-1 can also be used, but SHA-2 is safer.)
You can store the hash of the password in the database and match it against when the user
logs in.
Related
I'm putting together an android client (and possibly in the future iOS, web portal, etc) and php mysql server. Server side I am currently using the PHPass library to hash and salt the incoming passwords.
Should I make the client send plain text passwords over HTTPS/SSL or should the client do some form of hashing first. For example should every client simply sha1 (or some other algorithm) every outgoing password?
Most websites will send the password plain-text over an encrypted connection SSL/HTTPS. Hashing the password client-side can be done, but the advantage is small and often client-side languages (JavaScrypt) are slow so you can calculate less rounds in the same time, what weakens the hash. In every case the server must calculate a hash as well to be safe.
The advantage is small, because if an attacker can do a ManInTheMiddle attack, he can also modify/remove the script (JS) which does the hashing. Only an encrypted connection with SSL/HTTPS can protect against a MITM attack, so you need SSL anyway.
In your case with an app, it looks slightly different. Because the user first has to install your software, there is no need to send a script to the client, so a MITM cannot modify this script. Moreover, the app can calculate the hash relatively fast (if it can run native code) and therefore can do enough rounds on client-side.
This is what i would do:
For easiness send the password plain-text over an encrypted SSL/HTTPS connection and calculate the slow BCrypt hash server side, as you do now.
Only if the load on the server grows too heavy, then you can move the calculation of the slow BCrypt hash to the client app. Still use HTTPS to send the hash, and then calculate an additional fast hash (e.g. SHA-256) on the server. This is more complex, because you have to exchange and store the salt separately.
Another disadvantage of hashing passwords on the client is that you cannot change the hashing algorithm or iteration count without also having to update your clients.
For JavaScript clients that is not a problem, but you cannot easily guarantee that your users will be on the most recent version of your native client.
So I would stick with sending plain passwords over HTTPS.
In the early days of HTTP, there was Digest authorization as an alternative to Basic authorization. Instead of the HTTP header
Authorization: Basic <credentials>
you would use
Authorization: Digest <credentials>
It was an algorithm that increased security by avoiding the password being sent as cleartext. This was in the days when TLS/SSL came at a performance cost so this was an alternative. However the algorithm meant the password had to be stored as cleartext on the server. So you had a choice of sending the password cleartext but having a hash on the server, or sending the password as a hash but having cleartext on the server.
Unsurprisingly, as martinstoeckli said in his answer, now that TLS/SSL is widespread and easy to implement, HTTPS is used instead. You can store the password as a hash on the server but not expose the plaintext password if it is intercepted by a MITM attacker.
I am developing an Android app. The app communicates with a server through a PHP API. Each user must create an account. So, the app has a login functionality. I am doing further research on how to be able to securely transfer data between client (Android app) and server. For example, a user sends, through a POST, request his username/password in order to login.
Based on what I have read, I can safely assume that in case someone “listens” the transaction between client and server he could steal the username/password combination and use it on order to login to the legitimate user’s account. Is that correct?
The solution to this problem is to encrypt the data (eg username and password) before sending them either from client or server. The data will be then decrypted by the recipient (client or server). I do that by using crypt/decrypt functions both on client (written in Java) and server (written in PHP). Each function has the same IV (initialization vector) and Secret Key (to be honest, I do not know much about the IV’s usage so forgive me if I say something wrong. I google around for information but any useful links would be really appreciated).
From what I read, the problem with this implementation is that the APK file could be decompiled from client side and get the IV and Secret Key. As a result, a listener could decrypt the data sent. Is that correct?
Trying to find a solution to this problem I have a suggestion and I would like your opinion. What if during user’s registration a unique IV and secret key are given to the each user. These values are stored both to a MySQL database (server side) and a SQLite database (client side). Whenever data needs to be sent trough a post request, the user’s id (could be something simple as an integer) and the data to be sent are encrypted using the unique IV/Secret Key for the individual user. These are stored locally so the “listener” has no access to them. Even if he decompile the APK he will just have access to his own IV/Secret Key that he already knows. Then on server side the data are decrypted using the same IV/Secret Key stored on the server. The same procedure is applied when data are sent from server to client.
Is this a correct approach?
Reusing the same symmetric key and same IV is extremely incorrect approach and must not be used ever.
Reusing the same key and IV will enable attacks where the attacker will be able to recover your secret key just be eavesdropping on the encrypted traffic for long enough. And when the attacker has your key he will be able to decrypt all and every past and future communications.
To secure the data transfer you should use HTTPS (or SSL/TLS directly if your data transfer protocol is not HTTP-based).
If your only concern is to securely communicate with the server i suggest you to install a ssl certificate to your server. Doing this way the communication will be secured by the underlying protocol. To facilitate your communication with the server for implementing ssl communication i suggest you to use aquery library, here's a link!.
Also dont forget to see the ca compatibility list for android.
Hope it helps.
This is a rather old question so i'm surprised it didn't have a more complete response. It seems you understand the concepts of symmetric encryption but you are missing knowledge of public/private key encryption. Look up RSA for a method of achieving public/private key encryption. With this, you can generate (via the assistance of a cryptographically secure RNG) new random keys as well as IVs at the start of each session to feed to your symmetric encryption system. This means that anyone listening from start to finish will not be able to make sense of your system short of brute forcing the RSA key or the symetric(AES?) key.
I am developing a Java SE based application (university intranet) for a computer security course that sends a password (AES ecrypted) of a registered user to a server via a HTTP request. It performs the following steps:
The user registers to the Intranet app.
The client sends an HTTP request containing the student's password, encrypted with AES.
The PHP script now decrypts the AES ciphertext and hashes it.
The hashed password is stored into the database.
Now from what I have read about AES, I would need a secret key as part of the encryption process. As the server script will need the secret key to decrypt the cipher, would it be a bad idea to use the same secret key each time? Once the script receives the ciphertext it will then use a one way hash function to store it on a database.
If you really want to use a symmetric cypher
Ok I assume you want two entities to communicate by entering the same key on each entity (such as the Bluetooth connection). In that case the question have already been asked and I let you google for some answer like this
What you certainly want is HTTPS
But apparently you just want a secure communication between a client and a server. In that case you need to use HTTPS(since you use HTTP). HTTPS does all that for you with a handshake and then relying on a symmetric key algorithm to ensure the communication.
How it fulfills your requirements
In your very case, if the login page is served in HTTPS:
the password will be de facto encrypted by the client when it is sent
it will be automatically decrypted by the server then you have to
hash it in PHP and store it into the database.
I agree with the other comments - HTTPS is the way to go if possible.
However, to answer your question directly, then yes - using the same secret key (on it's own / without a salt) each time is a very bad idea. If, for some reason, HTTPS is not an option, then consider at least using a salt and/or a one-time-pad, depending on your implementation possibilities:
Salt (cryptography)
One-time Pad
This article looks like it might be useful:
Data Encryption Decryption using AES Algorithm, Key and Salt with Java Cryptography Extension
Hope that helps.
I need a solution to store all my network passords in a secure database. For that, I was thinking of Keepass. Now once the kdb (keepass DB) or something similar has been created, I would like to access it programatically preferably via Java.
I was also thinking of developing my own solution. Its a client/server architecture. The server will store all the passwd in gpg format. The clients will have the private key for decrypting the password received from the server. Only the clients with the correct private key can get decrypt the passwords. The private key will be embedded within the program.
Thanks,
Neel
I am trying to make a PHP script to interact a with a Java application. They will share some information, so I would like to encrypt the data that is passed between them to make it as secure as possible, on top of having an SSL certificate. However, because my website is only on a shared server at JustHost, as far as I am aware I can not use the 'mcrypt' PHP module, so I'm not sure how to do it so that both my Java application and the PHP script can encrypt data being sent and decrypt data being received!
Your SSL conversation between Java and PHP will protect it your data while it's in transit. Should you properly protect the private key with a strong password (10+ symbols) and make sure your algorithms strong no one will be able to break it by snooping on the conversation.
You won't get any extra protection by encrypting the data before sending it over the SSL conversation. And you actually might be weakening your security because in order for you to encrypt data you'll have to share some key should you choose symmetric encryption. And, by trading secret keys you're undoing much of the protection SSL gives you because the huge benefit of SSL is the fact we can encrypt data without agreeing on a secret key. If I were trying to get at your encrypted text I'd attack your client because it's easier to find your symmetric encryption key than it is to break SSL. And while you could use asymmetric encryption you'll be basically re-inventing SSL.
I would focus on making sure your SSL conversation is strong. Using only the strongest symmetric encryption: TripleDES, IDEA, AES if your server supports it. Take out the weaker algorithms so conversations can't use the weaker encryption. Generate 1024+ public/private key pairs. That might not always be easy on your shared server, but your Java application could only choose to use TripleDES, IDEA, and AES.
Make sure you validate the server's certificate on the client side so you ensure you aren't talking to a false service. That basically means taking the server's certificate and adding it to the keystore used on the client. If that's Java you can use keytool to import a certificate and use that keystore as your TrustManager/KeyManager in your SSL conversation.
If you want to encrypt the data after it's gone over the SSL conversation then you can encrypt/decrypt on the server only. But, you still have a key management problem. If you encrypt/decrypt how do you plan on securing the secret key on the server? That's always the ugly problem that doesn't have a simple answer.