12.5. Two Step Enrollment

Starting with version 2.21 privacyIDEA allows to enroll smartphone based tokens in a 2step enrollment.

With the rise of the smartphones and the fact that every user has a smartphone, carries it with him all the time and cares about it a lot, using the smartphone for authentication gets more and more attractive to IT departments.

Google came up with the Key URI 1 to use a QR code to easily enroll a smartphone token, i.e. transport the OTP secret from the server to the phone. However this bears some security issues as already pointed out 2.

This is why privacyIDEA allows to generate the OTP secret from a server component and from a client component (generated by the smartphone). This way the enrolled token is more tightly bound to this single smartphone and can not be copied that easily anymore.

12.5.1. Workflow

In a two step enrollment process the user clicks in the Web UI to enroll a token. The server generates a QR code and the user will scan this QR code with his smartphone app. The QR code contains the server component of the key and the information, that a second component is needed.

The smartphone generates the second component and displays this to the user.

The user enters this second component into the privacyIDEA Web UI.

Both the smartphone and the server calculate the OTP secret from both components.

12.5.2. Two Step policies

Two step enrollment is controlled by policies in the admin/user scope and in the enrollment scope.

Thus the administrator can allow or force a user (or other administrators) to do a two step enrollment. This way it is possible to avoid the enrollment of insecure Google Authenticator QR codes in the complete installation. (hotp_2step and totp_2step).

The default behaviour is to not allow a two step enrollment. Only if a corresponding admin or user policy is defined, two step enrollment is possible.

12.5.2.1. Key generation

In addition the administrator can define an enrollment policy to specify necessary parameters for the key generation.

Two step enrollment is possible for HOTP and TOTP tokens. Thus the administrator can define token type specific policies in the scope enrollment: hotp_2step_clientsize, totp_2step_clientsize, hotp_2step_difficulty… see {type}_2step_clientsize, {type}_2step_serversize, {type}_2step_difficulty.

12.5.3. privacyIDEA Authenticator

The privacyIDEA Authenticator 3 that is available from the Google Play Store supports the two step enrollment.

12.5.4. Specification

The two step enrollment simply adds some parameters to the original Key URI.

2step_output

This is the resulting key size, which the smartphone should generate (in bytes).

2step_salt

This is the length of the client component that the smartphone should generate (in bytes).

2step_difficulty

This is the number of rounds for the PBKDF2 that the smartphone should use to generate the OTP secret.

The secret parameter of the Key URI contains the server component.

The smartphone app then generates the client component, which is 2step_salt random bytes. It is then displayed in a human-readable format called base32check:

b32encode(sha1(client_component).digest()[0:4] + client_component).strip("=")

In other words, the first four bytes of the client component’s SHA-1 hash are concatenated with the actual client component. The result is encoded using base32, whereas trailing padding characters are removed.

The second step of the enrollment process is realized as another request to the /token/init endpoint:

POST /token/init

serial=<token serial>
otpkey=<base32check(client_component)>
otpkeyformat=base32check

Server and smartphone app then use PBKDF2 to generate the final secret (see 4 for parameter names):

secret = PBKDF2(P=hexlify(<server component>),
                S=<client component>,
                c=<2step_difficulty>
                dkLen=<2step_output>)

whereas hexlify(<server component>) denotes a hex-encoding (using lowercase letters) of the byte array which comprises the server component.

Note

Please note that the two-step enrollment process is currently not designed to protect against malicious attackers. Depending on the choice of iteration count and salt size, an attacker who knows the server component and an OTP value may be able to obtain the client component with a brute-force approach. However, two-step enrollment is still an improvement to the status quo, as a simple copy of the QR code does not immediately leak the OTP secret and obtaining the OTP secret using brute-force is not trivial.

1

https://github.com/google/google-authenticator/wiki/Key-Uri-Format

2

https://netknights.it/en/the-problem-with-the-google-authenticator/

3

https://play.google.com/store/apps/details?id=it.netknights.piauthenticator

4

https://www.ietf.org/rfc/rfc2898.txt