An alternative I think would be to encrypt the password, generate a hash to prevent it from being changed while sending to the server and generate a sort of device signature hash so the server knows that the password came from a device with the application installed and concatenate everything would look like this:
Never invent your own encryption! The chances of something going wrong are huge. Instead, use a well-established protocol for what you want:
Connect to your server using SSL/TLS. So the data you send to it will already be confidential and intact, it is not necessary to encrypt the password or generate a hash (incidentally, a hash does not prevent it from being changed during sending; a MAC maybe, but this is another story). And if you combine this with a customer authentication using certificates, you already guarantee the authenticity too, just send only the same simple password and ready!
If you need to store the user password on the device (it is not clear in the question if the user will have to type it every time you connect to your server, or if it will be saved on the device), look for some feature of the system itself to help you. I have no experience with Android, but a quick search brought me the AccountManager
- which seems to me to be a centralized means of managing the accounts that the user has in various services. I suggest to study it.
Detailing
If what I explained above was not clear, let me break the problem down into smaller pieces to make it easier to understand the proposed solution (and maybe present some alternatives):
Saving passwords on the device
Unless you want the user to enter their password every time they connect to your server, you need some method of authentication to be stored on the device. In this case, you cannot hash the password because you need the password in its original format to send to the server (otherwise hash becomes the password, and any attacker who gets a copy of the hash already has the credentials necessary to authenticate with the server). Encryption is an idea, but where to keep the key? This is a complicated situation, hence my suggestion to use what you already have ready on Android and get it out of your head...
Communicating safely with the server
If you do not use SSL/TLS (e.g., HTTPS), you cannot guarantee that communication with the server will not be intercepted and even modified (particularly on open networks). Trying to "turn around" without TLS will leave you with an unsafe solution and/or force you to reinvent many wheels. So I strongly suggest using this protocol.
When creating a secure channel via TLS, you can send the user credentials in flat format without the need to encrypt. Because the protocol guarantees the confidentiality (i.e. no one can read the communication) and the integrity (no one can change the communication) of both, in addition to the authenticity of the server (the client knows he is communicating with the right server).
Authenticating the device
In the question you show concern about the device that originated the request ("...so the server knows that the password came from a device with the application installed..."). That is, in addition to authenticating the user with the server, you also want to authenticate the device with the server.
At first, this can also be done via SSL/TLS, using customer certificates. Roughly, when installing the application it would generate a certificate for that device, register that certificate on the server (or simply have that certificate signed by an CA that the server trusts)and then when communicating via TLS would use that certificate with the protocol. So both client and server would be authenticated to each other, and it would be enough then you authenticate the user (sending the password in its normal format).
If all this is too complicated, a simpler alternative would be to generate a random password to be the "device password", and register it on the server next to the user’s password. This password would then be sent during authentication, also under the previously established secure channel.
Saving passwords on the server
On the server, of course, you will not store the password(s) in flat format, but a hash(s) of the same(s). See the question "How to hash passwords securely?" for more details.
Duplicate(?), related: How to hash passwords securely?
– Renan Gomes
Is it really necessary to store the password on the user’s device? If your application will be able to decrypt the password, so will a malicious user. Ideal in this case is to use a web service.
– André Ribeiro
@André Ribeiro I know this, but my application will be of online and offline use, in this case I have a suggestion that may be useful, but I do not know how I could implement it, I will edit the question with my suggestion.
– Gustavo Almeida Cavalcante
@Renan Duplicate not that link refers to the use of hash and mine is encryption that is a well improved hash.
– Gustavo Almeida Cavalcante
I don’t understand what the app has to do with saving passwords locally and offline.
– Pablo Almeida
@Pablo It has to do because the user will be able to login to the application even without internet (offline), he will be able to login and login even if offline understands?
– Gustavo Almeida Cavalcante
And in case I will save on the server because as the application will have a desktop version the user will be able to download his server profile and use on desktop and mobile.
– Gustavo Almeida Cavalcante
@Gustavoalmeidacavalcante Cryptography is not "a well-improved hash", the function of the hash is from an input to generate a unique value that represents it but it is not possible to do the reverse process (get the original data from the hash). The function of cryptography is to transform one data into another, unreadable, and then turn it back into the original data with the aid of a secret value (password or key). They are different techniques, applicable in different situations. Usually to protect passwords is using hashes, encryption is useless in this sense (see André Ribeiro’s comment).
– mgibsonbr
– Roger Barretto