Hello. Recently discussed an article about
one-time passwords . I would like to add it a little bit, because it is impossible to develop this topic, forgetting about such equally important areas of work with the user as registration and password change.
This post will be only a proposal in the authorization system based on sockets and can not yet claim to be implemented. Although I am sure that such a thing has already been implemented somewhere, long before me, but I think it will be interesting to reflect on the community on this topic.
So, we have a number of tasks that need to be performed:
- Create a mechanism to automatically authorize the client on the server.
- Implement the most secure password transfer mechanism during authentication, in which stealing a password hash will be absolutely pointless.
- Make the password change mechanism safe.
- Create a secure client registration mechanism.
')
Data and conditions of the problem
We have a fully closed server running on
sockets / web sockets , and there is a client application that can be broken and opened. We cannot rest against any static data in the client application (keys, key generation algorithms and other things that can be easily predicted by the usual decryption of the client).
For maximum complexity, our client is written in JavaScript as a desktop program on node-webkit . That is, anyone can get into the source code of the client and find out absolutely all the information he needs.
1. Automatic authorization mechanism
The client is provided with an authorization form, he enters his data into it, and after clicking the "Authorize" button, the application pulls out the login and password data. Login leave open - this is not critical information. With the password we start to work small miracles:
- We hash the password so that the virus could not see the clean user password.
- The password hash must be encrypted by key and stored in the permanent storage on the client. This is done with the aim of its reuse. If you leave an open hash, then the virus, having stolen this hash, will be able to authorize on the server without knowing the main password. As a key, it will be best to take some system information from a computer, for example, the mac-address of a network card, production numbers of iron or something else that may be a permanent key for decryption. This will not give 100% security in case of a virus penetration, but it will complicate the work of the hacker.
- With automatic authorization, the encrypted hash will be decrypted and shared with some data.
Main problems
Alas, we can’t do anything with keyloggers and other urgent infections, which will be done with direct passwords, but we put it well to evil-doers
2. Secure Login
So, we have a password hash. Next we need to produce a salting of this very password. Due to the fact that our application is also online, we will use as salt:
- Password hash
- External user IP
- Timestamp for password salting
- Login (optional)
External ip
Let's start with an external IP, which we can get easily and simply. At nodeJS, this is done as follows (exceptions and other things are missing).
var socket = require('net').createConnection(80, 'google.com');
One-time password with current time
The essence of one-time passwords is already clear, but we will complicate this system a little because of the common problem of time out-of-sync on the server and client. Now the client will request the current time from the server, thereby opening the server, and create only a time window for authorization. For example, we requested the current time from the server. The server gave the current time and opened the opportunity to log in within 30 seconds (for example). If during this period of time the authorization data did not come, the server will no longer give the right to log in until a new window is requested from it.
We immediately kill 2 birds with one stone: desynchronization of time and interception of hash.
Server decryption
Now a little about working on the server. When the hash comes to us, we will have to make the same identical hash. We have a hash of the password itself (stored in the database). We have a time window for authorization, we have a connected user's IP address. We can easily create the same hash and authorize it.
Main problems
An attacker will have only 30 seconds to log in to this hash and, because we have added some salt to our hash with an IP address, he must send this hash from the same external IP address, which makes it very difficult for him to work if he is not in the same network with the victim. If a thief is sitting in a different place and cannot access the Internet from the same IP address, then it becomes impossible to log in to the system.
Here I have a question for the knowledgeable. Can an attacker take control of the communication flow to himself so that the server does not notice the client substitution?
3. Password change mechanism
Although this action rarely happens, there is a chance that the new password will be intercepted through his shift. I examined this site for a long time and could not think of anything better than using an SSL / TSL connection to protect the hash of a new password.
You can try to make a mechanism for changing the password via SMS. The client will send an SMS message to a specified number with a new password. If the system requires serious protection, then this mechanism can and be used.
Main problems
If you do not use SSL / TSL, then a new hash can be snagged by the attacker, but by using the transfer of a password through other sources of communication this can be avoided.
4. Registration
There is the same problem as with a changeable password. It is necessary to somehow transfer the hash to the server so that the attacker does not snitch it.
You can send the client via SMS / Mail his password, which he can change based on the secure password change, or we can again use SSL / TSL for protection.
Main problems
We again came up against the problem of transferring the password to the server, there are only 2 options for saving. This is either an encrypted communication channel or an alternative password transfer route to the server.
The implementation of the password transfer should occur depending on the complexity of the task. As you know, if it is difficult to break and the result will not be worth the money, they will not break it.
Pressing issues
People will mention such things as proxies, dynamic IPs and other things. Now we will sort them out.
1) Dynamic IP
As you know, if the IP changes, the connection with the server is broken. It is simply reset. You need to repeat the authorization procedure again. It is quite possible to make the reconnection not noticeable to the user by implementing a reconnect on the client and re-finding out the external IP. So we will be sure that the client will be able to connect to the server without any obstacles via a new one.
2) Proxy
Fortunately, the proxy can not disrupt the normal operation of the client. If the client uses open proxy, then he exposes himself to the danger of interception of authorization and will be his own evil Pinocchio.
It would be desirable, that users of a habr added here still the questions or problems which can arise.
Only for
This algorithm has the right to life only in systems where authorization with the server occurs over sockets / web sockets. I have not yet been able to understand how this authorization algorithm can be applied to http requests, because we run up against the limitations of the protocol itself, we cannot perform client-> server-> client-> server communication. The last node does not work anymore due to the protocol specification (although maybe I am wrong).
Article continuation
If this article can withstand criticism, I will implement this mechanism in JavaScript (node-webkit) and Python so that you can already poke this system for physical vulnerabilities that could be missed in this article.
Thank you all, I am waiting for constructive criticism and comments.