Kaip veikia vienkartiniai slaptažodžiai pagal laiką ir kodėl turėtumėte juos naudoti savo programoje.

Didėjant kibernetinio saugumo grėsmėms, vis labiau reikia atnaujinti savo žiniatinklio programų saugos standartus. Turite įsitikinti, kad jūsų vartotojų paskyros yra saugios.

Šiuo metu daugybė internetinių programų prašo vartotojų pridėti papildomą savo paskyros saugumo lygį. Jie tai daro įgalindami dviejų veiksnių autentifikavimą. Dviejų veiksnių autentifikavimui įgyvendinti yra įvairių būdų, o TOTP („Time-based One-Time Password“ algoritmas) autentifikavimas yra vienas iš jų.

Šiame straipsnyje paaiškinta, kas tai yra, kaip ir kodėl jį naudoti. Tačiau prieš tai suprasdami, pirmiausia trumpai apžvelkime, ką reiškia dviejų veiksnių autentifikavimas.

Kas yra dviejų veiksnių autentifikavimas?

Dviejų veiksnių (arba kelių veiksnių) autentifikavimas yra tik papildomas vartotojo paskyros saugumo sluoksnis. Tai reiškia, kad įjungęs dviejų veiksnių autentifikavimą, vartotojas turi atlikti dar vieną žingsnį, kad sėkmingai prisijungtų. Pavyzdžiui, įprasti prisijungimo prie paskyros veiksmai yra šie:

Bet įgalinus dviejų veiksnių autentifikavimą, veiksmai atrodo maždaug taip:

Taigi tai prideda dar vieną žingsnį prie prisijungimo proceso. Šis metodas yra saugesnis, nes nusikaltėlis negali pasiekti vartotojo paskyros, nebent jis turi prieigą ir prie vartotojo įprasto slaptažodžio, ir prie vieno slaptažodžio.

Šiuo metu yra du plačiai naudojami būdai, kaip gauti vieną kartą naudojamą slaptažodį:

  1. SMS pagrindu: taikant šį metodą, kiekvieną kartą, kai vartotojas prisijungia, jis gauna tekstinį pranešimą į savo registruotą telefono numerį, kuriame yra vienkartinis slaptažodis.
  2. Remiantis TOTP: taikant šį metodą, įgalinant dviejų veiksnių autentifikavimą, vartotojo prašoma nuskaityti QR vaizdą naudojant tam tikrą išmaniojo telefono programą.

    Tuomet ta programa vartotojui nuolat generuoja Vienkartinį slaptažodį.

SMS metodu nereikia paaiškinti. Tai lengva, bet turi savų problemų, tokių kaip SMS laukimas kiekvieną kartą bandant prisijungti, saugumo problemos ir pan. TOTP pagrįstas metodas tampa populiarus dėl savo pranašumų, palyginti su SMS metodu. Taigi supraskime, kaip veikia TOTP pagrįstas metodas.

Kaip veikia TOTP pagrįstas metodas

Prieš tai suprasdami, pirmiausia aptarkime, kokias problemas mums išspręs šis metodas.

Naudodami TOTP metodą, mes sukuriame vienkartinį slaptažodį vartotojo pusėje (vietoj serverio pusės) per išmaniojo telefono programą.

Tai reiškia, kad vartotojai visada turi prieigą prie savo vieno slaptažodžio. Taigi jis neleidžia serveriui siųsti teksto pranešimo kiekvieną kartą, kai vartotojas bando prisijungti.

Be to, sugeneruotas slaptažodis pasikeičia po tam tikro laiko intervalo, todėl jis elgiasi kaip vienkartinis slaptažodis.

Puiku! Dabar supraskime TOTP metodo veikimą ir pabandykime patys įgyvendinti aukščiau pateiktą sprendimą. Mūsų reikalavimas yra sukurti slaptažodį vartotojo pusėje, ir šis slaptažodis turėtų nuolat keistis.

Tai gali būti būdas įgyvendinti šį sprendimą:

When the user enables two factor authentication:
1. Backend server creates a secret key for that particular user.2. Server then shares that secret key with the user’s phone application.3. Phone application initializes a counter.4. Phone application generate a one time password using that secret key and counter.5. Phone application changes the counter after a certain interval and regenerates the one time password making it dynamic.

Tai turėtų veikti, tačiau yra trys pagrindinės problemos:

  1. Kaip programa sugeneruos vienkartinį slaptažodį naudodama slaptą raktą ir skaitiklį?
  2. Kaip atnaujinamas skaitiklis? Kaip žiniatinklio serveris stebės skaitiklį?
  3. Kaip serveris pasidalins slaptu raktu su telefono programa?

Pirmosios problemos sprendimas yra apibrėžtas HOTP algoritme.

Suprasti HOTP:

HOTP reiškia „HMAC pagrįstas vienkartinis slaptažodis“. Interneto inžinerijos darbo grupė (IETF) šį algoritmą paskelbė kaip RFC4226. HOTP apibrėžia algoritmą, kaip sukurti vienkartinį slaptažodį iš slapto rakto ir skaitiklio.

Šį algoritmą galite naudoti dviem veiksmais:

  1. Pirmas žingsnis - sukurti HMAC maišos iš slapto rakto ir skaitiklio.
// Obtain HMAC hash (using SHA-1 hashing algorithm) by secretKey and counter
hmacHash = HMAC-SHA-1(secretKey, counter);

2. Šiame kode išvestis būtų 20 baitų ilgio eilutė. Ta ilga eilutė netinka kaip vienkartinis slaptažodis. Taigi mums reikia būdo sutrumpinti tą stygą. HOTP apibrėžia būdą, kaip tą eilutę sutrumpinti iki norimo ilgio.

// hmacHash[19] means 19th byte of the string.offset = hmacHash[19] & 0xf;
truncatedHash = (hmacHash[offset++] & 0x7f) << 24 | (hmacHash[offset++] & 0xff) << 16 | (hmacHash[offset++] & 0xff) << 8 | (hmacHashh[offset++] & 0xff);
finalOTP = (truncatedHash % (10 ^ numberOfDigitsRequiredInOTP));

It might look scary, but it is not. In this algorithm, we first obtain offset which is the last 4 bits of hmacHash[19]. After that, we concatenate the bytes from hmacHash[offset] to hmacHash[offset+3] and store the last 31 bits to truncatedHash. Finally, using a simple modulo operation, we obtain the one time password that’s a reasonable length.

This pretty much defines the HOTP algorithm. The RFA4226 doc explains why this is the most secure way to obtain a one time password from these two values.

Great! So we have found a way to obtain a one time password using a secret key and counter. But what about the second problem? How to keep track of the counter?

The solution to second problem is found in the TOTP.

Understanding TOTP:

TOTP stands for “Time-Based One-Time Password”. This was published as RFC6238 by IETF.

A TOTP uses the HOTP algorithm to obtain the one time password. The only difference is that it uses “Time” in the place of “counter,” and that gives the solution to our second problem.

That means that instead of initializing the counter and keeping track of it, we can use time as a counter in the HOTP algorithm to obtain the OTP. As a server and phone both have access to time, neither of them has to keep track of the counter.

Also, to avoid the problem of different time zones of the server and phone, we can use a Unix timestamp, which is independent of time zones.

However the Unix time is defined in seconds, so it changes every second. That means the generated password will change every second which is not good. Instead, we need to add a significant interval before changing the password. For example, the Google Authenticator App changes the code every 30 seconds.

counter = currentUnixTime / 30

So we have solved the problem of the counter. Now we need to address our third problem: sharing the secret key with the phone application. Here, a QR code can help us.

Using a QR code

Though we can ask the users to type the secret key into their phone application directly, we want to make secret keys quite long for security reasons. Asking the user to type in such a long string would not be a user friendly experience.

Since the majority of smartphones are equipped with a camera, we can use it and ask the user to scan a QR code to obtain the secret key from it. So all we need to do is to convert the secret key in the QR code and show it to the user.

We have solved all three problems! And now you know how TOTP works. Let’s see how to implement it in an application.

How to implement TOTP

There are some free phone applications (like Google Authenticator App, Authy, and so on) available which can generate an OTP for the user. Therefore, in most cases, creating your own phone application is not necessary.

The following pseudo codes explain a way to implement TOTP-based 2-factor authentication in a web application.

When user request to enable 2-factor authentication
// Generate a secret key of length 20.secretKey = generateSecretKey(20);
// Save that secret key in database for this particular user.saveUserSecretKey(userId, secretKey);
// convert that secret key into qr image.qrCode = convertToQrCode(secretKey);
// send the qr image as responseresponse(qrCode);

The user is asked to scan that QR code. When the phone application scans the QR code, it gets the user’s secret key. Using that secret key, the current Unix time, and the HOTP algorithm, the phone application will generate and display the password.

We ask the user to type the generated code after scanning the QR code. This is required, because we want to make sure that the user has successfully scanned the image and the phone application has successfully generated the code.

User types the code displayed in the application.
// Fetch secret key from database.secretKey = getSecretKeyOfUser(userId);
if (codeTypedByUser == getHOTP(secretKey, currentUnixTime / 30)) { enableTwoFactorAuthentication(userId);}

Here we use the HOTP algorithm on the server side to get the OTP-based authentication on the secret key and current unix time. If that OTP is the same as the one typed by the user, then we can enable 2-factor authentication for that user.

Now after every login operation, we need to check if this particular user has 2-factor authentication enabled. If it is enabled, then we ask for the one time password displayed in the phone application. And if that typed code is correct, only then is the user authenticated.

User types the code displayed in the phone application to login
// Fetch secret key from database.secretKey = getSecretKeyOfUser(userId);
if (codeTypedByUser == getHOTP(secretKey, currentUnixTime)) { signIn(userId);}

What happens if the user loses the code?

There are a couple of ways to help the user to recover the code. Usually when they are enabling 2-factor authentication, we can show the secret key to them along with the QR code and ask them to save that code somewhere safely.

Applications like Google Authenticator App let you generate the password by directly entering the secret key. If the user loses the code, they can enter that safely saved secret key in the phone application to generate the OTP again.

Jei mes turime vartotojo telefono numerį, mes taip pat galime naudoti SMS pagrįstą metodą, norėdami nusiųsti vartotojui OTP, kad padėtų atkurti kodą.

Apvyniojimas

Populiarėja dviejų veiksnių autentifikavimas. Daugybė interneto programų ją įdiegia, kad būtų užtikrintas didesnis saugumas.

Skirtingai nei SMS metodu, TOTP metodas taip pat nereikalauja daug papildomų pastangų. Taigi šią funkciją verta įdiegti bet kuriai programai.