BLOG POSTS
Many Common Mobile Authenticator Apps Accept QR Codes for Modes They Don't Support
By Laban Sköllermark (@LabanSkoller)
You probably use an “authenticator app” such as Google Authenticator to enable two-step verification (sometimes called two-factor authentication, 2FA, or multi-factor authentication, MFA) for an online account. The method is called Time-Based One-Time Password Algorithm (TOTP) and is standardized in
- Authy 2-Factor Authentication
- Duo Mobile
- Google Authenticator
- LastPass Authenticator
- Microsoft Authenticator
- Sophos Authenticator
- Symantec VIP Access
- Yubico Authenticator
Conclusion
EDIT: This section except for the last paragraph was accidentally deleted before publication and was restored two hours later. Thanks, git log -S Conclusion --walk-reflogs --patch
!
The de-facto standard is to transfer TOTP parameters including the secret (key) using a QR code. It seems Google invented this method. The QR code encodes text on the so called Key URI format as per a Google Authenticator wiki article:
otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30
The TOTP standard recommends a default time-step size of 30 seconds. Many apps support 60 seconds as well. The HMAC-SHA-1 hash function is the default but HMAC-SHA-256 and HMAC-SHA-512 are also allowed. The Key URI format says
The digits parameter may have the values 6 or 8, and determines how long of a one-time passcode to display to the user. The default is 6.
Varying the number of digits is not mentioned in the TOTP standard apart from in the Java reference implementation, but it’s mentioned as an extension in the underlying HMAC-Based One-Time Password Algorithm (HOTP) standard (
A simple enhancement in terms of security would be to extract more digits from the HMAC-SHA-1 value. For instance, calculating the HOTP value modulo 10^8 to build an 8-digit HOTP value would reduce the probability of success of the adversary from sv/10^6 to sv/10^8.
My investigations show that many common mobile authenticator apps accept QR codes for hash algorithms, periods and number of digits they don’t support. Instead they assume the standard settings and generate tokens based on that, giving wrong tokens, no error messages and a bad user experience. Sites providing TOTP as a two-step verification method usually require the user to provide one token to prove that it has saved the TOTP parameters, the device has correct time and so on so there is no risk that these shortcomings would lock out users from their accounts, but there is a risk that a user would skip two-step verification if the setup process fails.
Recommendation to App Developers
I recommend authenticator app developers to validate the data from the QR code, check if the app supports the mode encoded in it and give the user a descriptive error message if it detects a setting which the app does not support. Even better would be to add support for all three SHA hash algorithms mentioned in the TOTP RFC (HMAC-SHA-1, HMAC-SHA-256 and HMAC-SHA-512), 6 and 8 digit tokens plus 30 and 60 second periods.
Recommendation to Site Owners
For sites choosing to let users protect their accounts with two-step verification via TOTP I recommend sticking to the HMAC-SHA-1 algorithm, 6 digits and a period of 30 seconds, at least as a default value, since this is currently the only mode all tested apps support. Choosing another mode is begging for problems for the users unless a list of compatible apps is presented to the user.
Tested Apps
The following table shows which apps I’ve tested on the two platforms, the versions and the dates they were updated. Note that the test was conducted in end of April 2019 and that several apps have gotten updates since then when this post is published. Links go to Google Play and Apple App Store.
Legend | |
---|---|
All tested modes supported | |
Only some modes supported but error messages on the others | |
Wrong tokens displayed for unsupported modes |
App | Platform | Version | Last Updated | |
---|---|---|---|---|
Authy 2-Factor Authentication | Android | 23.7.0 | 15 APR 2019 | |
Authy | iOS | 22.4.1 | 24 APR 2019 | |
Duo Mobile | Android | 3.27.0 | 25 APR 2019 | |
Duo Mobile | iOS | 3.25.0 | 03 APR 2019 | |
Google Authenticator | Android | 5.00 | 27 SEP 2017 | |
Google Authenticator | iOS | 3.0.1 | 13 SEP 2018 | |
LastPass Authenticator | Android | 1.2.0.1179 | 12 APR 2019 | |
LastPass Authenticator | iOS | 1.5.6 | 15 NOV 2018 | |
Microsoft Authenticator | Android | 6.4.7 | 01 APR 2019 | |
Microsoft Authenticator | iOS | 6.2.8 | 12 MAR 2019 | |
Sophos Authenticator | Android | 3.1 | 25 MAR 2017 | |
Sophos Authenticator | iOS | 1.4.0 | 03 MAY 2017 | |
Symantec VIP Access | Android | 4.1.6 | 06 MAR 2019 | |
Symantec VIP Access | iOS | 4.2.4 | 27 SEP 2018 | |
Yubico Authenticator * | Android | 2.1.0 | 24 SEP 2018 |
*) Yubico doesn’t have an authenticator app for iOS, but that might change when YubiKey 5Ci is released.
Generation of Test QR Codes
In order to test the different apps I chose to generate a set of QR codes with different modes, scan them with all tested apps and then set the phone’s clock to a given test time (2019-04-28 13:37:00 CEST).
I know that the secrets below should be longer for HMAC-SHA-256 (32 bytes) and HMAC-SHA-512 (64 bytes) than for HMAC-SHA-1 (the HOTP RFC recommends 20 bytes), but it doesn’t matter since the Keyed-Hashing for Message Authentication (HMAC)
The following Bash for
loop was used to produce the QR codes in PNG format using qrencode
3.4.4 (man page):
$ for algorithm in SHA1 SHA256 SHA512
> do
> for digits in 6 8
> do
> for period in 30 60
> do
> qrencode -o "AA_${algorithm}_${digits}_${period}s.png" \
> "otpauth://totp/labanskoller.se:AA_${algorithm}_${digits}dig_${period}s@labanskoller.se?algorithm=${algorithm}&digits=${digits}&issuer=labanskoller.se&period=${period}&secret=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
> done
> done
> done
Resulting 12 QR codes:
Generation of Tokens to Compare With
The correct tokens to check against for the chosen test time were produced with oathtool
2.6.2 (man page):
$ for algorithm in SHA1 SHA256 SHA512
> do
> for digits in 6 8
> do
> for period in 30 60
> do
> printf "%-18s: " "AA_${algorithm}_${digits}dig_${period}s"
> oathtool --base32 --totp="${algorithm,,}" \
> --time-step-size "${period}" \
> --now "2019-04-28 13:37:00 CEST" \
> --digits "${digits}" \
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
> done
> done
> done
AA_SHA1_6dig_30s : 365290
AA_SHA1_6dig_60s : 205069
AA_SHA1_8dig_30s : 22365290
AA_SHA1_8dig_60s : 45205069
AA_SHA256_6dig_30s: 986416
AA_SHA256_6dig_60s: 727026
AA_SHA256_8dig_30s: 65986416
AA_SHA256_8dig_60s: 94727026
AA_SHA512_6dig_30s: 573802
AA_SHA512_6dig_60s: 759363
AA_SHA512_8dig_30s: 75573802
AA_SHA512_8dig_60s: 15759363
Findings
Below the findings for every app are listed. The support for the different hash algorithms, number of digits and the periods are always included but some other interesting findings are also added. Any noteworthy differences between Android and iOS are covered.
Authy 2-Factor Authentication
Android: | Wrong tokens displayed for unsupported modes | |
iOS: | Wrong tokens displayed for unsupported modes |
- Only supports HMAC-SHA-1 but accepts the other two algorithms as well without error messages and generates erroneous tokens
- Only supports 30 second periods but accepts 60 second periods as well without error messages and generates erroneous tokens
- Correctly supports 8 digits however
- Is fetching the current time from some kind of backend to correct for wrong time on mobile device but this feature can’t be turned off without entering flight mode (and then the offset still applies so the offset must be zero before enabling flight mode in order to accept the phone’s time)
- Android: Blocks ability to take screenshots
Duo Mobile
Android: | Wrong tokens displayed for unsupported modes | |
iOS: | Wrong tokens displayed for unsupported modes |
- Android: Blocks ability to take screenshots (but it can be temporarily unlocked for 10 minutes!)
- Only 6 digit modes are supported
- 8 digit modes are correctly rejected
- Only 30 second periods are supported
- 60 second periods are accepted without error messages and generate erroneous tokens
- The only supported algorithm is HMAC-SHA-1 (6 digits and a 30 second period)
- The app accepts any other of the tested modes with 6 digits without error messages and generates erroneous tokens
- The token generated when an entry is clicked is always shown for 30 seconds even if the token is just valid for e.g. one second according to the clock. This is not a huge problem as long as the recommendation (not a requirement) about accepting the client being a few time steps out of sync is honored (see section 6 Resynchronization in the TOTP RFC). It makes the period the token is valid for unnecessary short though.
Google Authenticator
Android: | Wrong tokens displayed for unsupported modes | |
iOS: | All tested modes supported |
- Android: The only supported mode is the HMAC-SHA-1 algorithm, 6 digits and a 30 second period
- Android: The app accepts any other of the tested modes without error messages and generates erroneous tokens
- iOS: Supports all tested modes
- iOS: The circle counting down to the next token always take 30 seconds for one round even if the period is 60 seconds
It’s funny that Google has broader support in their iOS app than in the app for their own OS.
LastPass Authenticator
Android: | Wrong tokens displayed for unsupported modes | |
iOS: | All tested modes supported |
- Android: The only supported algorithm is HMAC-SHA-1 but the other two are accepted without error messages and generates erroneous tokens
- Android: Blocks ability to take screenshots
- iOS: Supports all tested modes
Microsoft Authenticator
Android: | Wrong tokens displayed for unsupported modes | |
iOS: | Wrong tokens displayed for unsupported modes |
- The only supported mode is the HMAC-SHA-1 algorithm, 6 digits and a 30 second period
- The app accepts any other of the tested modes without error messages and generates erroneous tokens on both platforms
Sophos Authenticator
Android: | All tested modes supported | |
iOS: | All tested modes supported |
- Supports all tested modes
- Android: 8 digit entries can’t be entered manually (only added by scanning QR code)
- iOS: When adding entries manually only the secret and period can be entered (not algorithm or number of digits), but once added also algorithm and number of digits can be modified
- Android: Entries added can’t be modified but renamed
Symantec VIP Access
Android: | Only some modes supported but error messages on the others | |
iOS: | Only some modes supported but error messages on the others |
- The only supported mode is the HMAC-SHA-1 algorithm, 6 digits and a 30 second period
- The user is presented with proper error messages for unsupported modes on both platforms
Yubico Authenticator
Android: | All tested modes supported | |
iOS: | No app |
- Android: Supports all tested modes
- Android: Warns when there is already a TOTP secret with the same issuer and name present on the YubiKey when adding a new entry
- Android: Blocks ability to take screenshots
- No iOS app yet
Summary
Many common mobile authenticator apps accept QR codes for hash algorithms, periods and number of digits they don’t support. They give wrong tokens, no error messages and therefore a bad user experience. I urge TOTP app developers to validate the data that comes from the scanned QR codes and present the user with a descriptive error message if they choose to not support all possible modes. I recommend site owners who support two-step verification using TOTP to give users guidelines on which apps to use if they choose a mode other than the most common HMAC-SHA1 algorithm, 6 digits and a period of 30 seconds.
The best app out of the tested ones is in my opinion Sophos Authenticator which supports all modes on both platforms. Symantec VIP Access is the second best since it doesn’t support all modes but it tells the user when a mode is not supported.
Comments?
Do you have comments? Interact with this tweet:
New blog post: Many Common Mobile Authenticator Apps Accept QR Codes for Modes They Don't Support#TOTP #Authenticationhttps://t.co/5YppKw4CVS pic.twitter.com/7JMb71jn0j
— Laban Sköllermark @LabanSkoller@infosec.exchange (@LabanSkoller) July 11, 2019
Credit
Icons made by Smashicons from www.flaticon.com licensed by CC 3.0 BY.
Thanks to Alexander Kjäll for reviewing halfway through the progress.