While making plans for my travels, I was wondering how to protect my administrator access to remotely accessible NAS. I noticed that this device offers two-factor authentication mechanism, which should increase security. This article will focus on this specific high level implementation.
What is the purpose of two-factor authentication? Basically, to give two independent passwords. First password is known by you only. Second password can be static like paraphrase used in ssh, or dynamic – changed periodically. Dynamic method is safer, because even if someone steals your password, without dynamic value they cannot logon to the system. My second password is being changed every 30 seconds.
The second (dynamic) method requires a special kind of pseudo-random generator. Both pseudo-random generators (the one that exists on the server and the second one on the external device) must be initialized by same seed. Both generators must be fully synchronized, which I think is clear why 😉 . The idea is not to store this seed on client computer used to log on to the system/server. Client’s pseudo-random generator should be realized as a hardware token or e.g. a mobile application. So the shared seed is not stored on the computer that you are using to authenticate but on a different, isolated device. As a result, on the computer that you are using to logon, you provide only the temporary secondary password, which is valid for a short time period.
Authentication scenario summary
Your authentication scenario looks like this:
- You logon to the system using your user name and password.
- System verifies your credentials and, if they are fine, asks you for the secondary password.
- You are checking the password on your device and type it in on the second logon screen. In my case – it is 6 digits.
- If everything is OK, you are logged on.
How to build a generator
How to write a pseudo-random generator? There is a simple way to do it. Let’s focus on the shortcut functions like SHA. When single bit of information is being changed, this function will generate different shortcut code. The probability of each shortcut bit switch oscillates about 50%, in this case – almost chaos. It means that we can create something like pseudo-random generator using shortcut functions. Now we have to define, how to implement seed and next value generation method. One of the way how to implement this pseudo-generator subsequent values is to use time difference between now and some past ‘base’ time. Time based generators are using UNIX ‘zero’ time as a start point.
Good news is that if we want to use 2FA, we do not need to build custom token device. As a token we can use a mobile application. I am currently using Google Authenticator for Android. To build server side you have to use exactly the same algorithm. Details about the implementation you can find here in ‘Pseudocode for One Time Password OTP’ section. As you probably know Google Authenticator is open source so you can base on its implementation too. See GitHub resources at google-authenticator and google-authenticator-android.
To share seed with Google Authenticator you have to options. Manually enter seed (called message in described algorithm) as base32 string – this solution is good, but less professional 😉 . The second option is to scan QR Code by Android device. The last thing you have to know, is how to encode string as QR Code. Helpful link can be found here Key-Uri-Format .
To create better protection of your critical resources, you can use two-factor authentication. You can use an already developed application as token device or, if you wish, you can build a custom one – Raspberry Pi might be a good choice 😉 . If you want to base it on Google Authenticator, you only have to implement QR Code URI generator, and pseudo-random generator on server side for password validation.