Dale Gravatt · Jul 15

$System.Encryption.TOTP Synchronization

Can the built-in $System.Encryption.TOTP() function be used in conjunction with Authenticator Apps (e.g. Google, Microsoft, and so on)?

Providing the same secret/key to a variety of authentication apps, they all return the same synchronized value. However, passing the same secret/key to $System.Encryption.TOTP() is generating a different value (with all instances executing at the same time for comparison).

All of the reference material I have found so far mentions RFC4226 or RFC6238 or both, including the Intersystems documentation. However, it appears that these other applications are adjusting the Unix Epoch to the local time offset, while the $System.Encryption.TOTP() function is using $ZTIMESTAMP (UTC without an offset) in Horolog format. Unfortunately, forcing the use of $HOROLOG instead of $ZTIMESTAMP, though changing the output, did not synchronize the output with these other implementations of the TOTP algorithm.

Any insights or suggestions from previous experiences utilizing TOTP with InterSystems applications would be appreciated.

Product version: Caché 2018.1
1 0 1 40
Log in or sign up to continue

Resolved. I discovered the reason for the difference.

The $System.Encryption.TOTP() function accepts a "plain text" secret that is then internally converted to Base32 encoding for use in the algorithm. The other applications do NOT convert the secret, but expect the Base32 encoded value to be supplied. Consequently, when passing a Base32 encoded secret to $System.Encryption.TOTP(), that value was re-encoded causing the generated output to be different than the other applications.

If you wish to use the built-in $System.Encryption.TOTP() function in conjunction with an Authentication App,  you will need to have both the "plain text" secret and the Base32 encoded secret available. The ObjectScript call will need the "plain text" secret and the Authentication App will likely need the Base32 encoded secret.