TOTP (Timed One Time Password) uses a secret which is a block of binary data. It suffers from being symmetric in that the server doing the checks, and the user (usually in an app on their phone) both have to know the same secret.
This presents the problem of getting this secret from one to the other. This story is about that journey.
A friend has a customer that wants to use some specific device they already have to provide OTP codes, and so has to send the secret to him to load on to the server.
Firstly, this is not quite how it is usually done - the usual way is the server makes a (new, random) secret, provides it to the customer (often as a QR code), who confirms receipt by entering the current OTP code. All done over https to be secure. Sorted.
But in this case the customer had the secret and wanted to send it.
As I say, the secret is just a small block of binary data, usually expressed as base32.
They sent, by email, an RFC6030 XML file, signed, with base64 coded encrypted secret in it. They also sent a simple 16 byte binary file which is the key, by email.
- The base64 had to be converted to binary
- The first 16 bytes extracted as IV
- The remaining bytes stored, in binary, as the encrypted data
- The IV had to be converted to hex for openssl command line
- The 16 byte binary key file had to be converted to hex for openssl command line
- openssl command line for AES-CBC was run and produced a binary decoded file
- This had to be converted to base32 and loaded on the system as the secret
Was this secure?
Short answer: no. Both parts sent by email. Sent as separate email as obviously no hacker could possibly intercept both emails!!!
Almost any secure messaging app, e.g. signal, interactively whilst talking to the contact, sent as base32, and ideally as a disappearing message.
Or email the base32 over PGP encrypted email.
Or, well, almost anything else! Reading the Base32 over the phone FFS (though phone calls are rarely encrypted in transit over the network).
Storing the key?
One thing done on the back end system, apart from encrypted disk, etc, is to store the secret encrypted with the users password and salt. The password is not stored, only an argon2 hash. This means you can validate a password+totp code, but you cannot extract either the password or the TOTP key from a leaked copy of the database. I mean, yes, if someone can get a copy of the system and database, and trojan a user in to entering password, they can decode the TOTP as well, but that requires that extra user interaction step for each compromised user record.
P.S. what is my involvement?
Mostly helping my friend out to understand what he had to do. We are all cautious to ensure security, as you would expect.