Lenght of TOTP key?

Hi, how long is the TOPT security in Nextcloud (using “Two-Factor TOTP Provider”)? How many bits.
Is it possible to harden it?


Not sure how exactley it is generated and how many bits that would be, but here’e an example:


Afaik no, but maybe you can add your thoughts to this issue on GitHub or open a new one.

Theoretical part:

The secret created by the TOTP App is 16 characters long and consists only of the characters A-Z and the numbers 2, 3, 4, 5, 6 and 7 (RFC 4648 Base32 alphabet)

Bit Length per Character = log2(Number of Possible Characters)

In this case:

Bit Length per Character = log2(32) = 5 bits per character

Since each character in the string “A-Z234567” represents 5 bits, if you create a 16-character string, the total bit length would be calculated as follows:

Total Bit Length = Number of Characters * Bit Length per Character
Total Bit Length = 16 characters * 5 bits per character = 80 bits

Here’s why (in other words):

  • There are 26 uppercase letters (A-Z) and 6 numbers (2-7), totaling 32 possible characters.
  • Each character can be represented using 5 bits in binary (since 2^5 = 32, which is the smallest power of 2 greater or equal to 32). So, 5 bits are needed to represent each character.

Therefore, when you have a 16-character secret composed of only these characters, the total bit depth is 16 characters * 5 bits per character = 80 bits.

My Google-TOTP secret generated by Google is 32 characters long (160 bit deep) and my Amazon secret is even 52 characters long (260 bit deep)

Practical part:

If you want to harden the security of your TOTP secret, you have to tampere the source code a little bit:

In the file:

it is the private function generateSecret() (line 74, 75) where the secret is created.

This is how it looks:

	private function generateSecret(): string {
		return $this->random->generate(16, ISecureRandom::CHAR_UPPER.'234567');

and you simply have to change the 16 into 32 or 52 or 64, whatever security you want.

Example how it looks for me:

	private function generateSecret(): string {
		return $this->random->generate(32, ISecureRandom::CHAR_UPPER.'234567');

That generates 32 signal long secrets.

You only need to set this as long as you generate new secrets. After the secret generation is done, you can change it back to 16, to prevent integrity-check failures. A hash of the created secret is stored in the database and in your TOTP authentictor app the secret is stored as well. (There is the place where you can make it visable).

I hope this helps,

much luck!

1 Like

In the end, doesn’t it all make perfect sense? With TOTP there are the possibilities 000000 to 999999 (6 digits) (e.g. Google Authenticator) for the input (also by the hacker). The result is 6 * log2 (10) = 19.9 bits. Isn’t it much more reasonable to overcome the 19.9 bit probability instead of the 80 bit?

Incidentally, this is perfectly adequate, since the PIN, unlike a password, is only valid for a very short time and more importantly it can be used only once. I think most attacks on normal passwords are done by keyloggers, where by the way the password length is irrelevant. Or they are hacked offline (hash decrypt). Both is with TOTP not possible.

Yes but useless and maybe a risik for security because of editing the code. You should leave it alone, as you probably have far less knowledge than a security expert.

See New hashing algorithm? · Issue #26 · nextcloud/twofactor_totp · GitHub

1 Like

Another problem is that e.g. Google Authenticator only supports 80 bit with HMAC-SHA-1

Google Authenticator - Wikipedia

HMAC - Wikipedia

SHA-1 - Wikipedia

That is not correct. The Google Authenticator app supports all bit depths.

→ RFC 4226 requires a minimum depth of 128 and recommends 160 bits ← . Google itself creates160-bit secrets for its accounts.

I don’t know why 80 bit secrets are still being created, especially since the SHA1 hash algorithm already has its weaknesses.
It is well known that the Google Authenticator is not very versatile. I use the Aegis Authentoicator, which can not only TOTP, but also HOTP, Steam, Yandex and MOTP, and can hash with SHA256 and SHA512 in addition to SHA1.

But no matter how you look at it, an 80 bit secret for a TOTP second factor is still many times safer than no second factor at all and it always depends on which value you want to protect. Most of us probably don’t have military secrets to secure. Nobody will propably bother to brute force a TOTP secret :wink:

Sorry found this at german Wikipedia

Google Authenticator verwendet einen nur 80 Bit langen Geheimcode; nach RFC 4226 sollte die Länge des Geheimcodes hingegen mindestens 128 Bit betragen, 160 Bit sind empfohlen.

Google Authenticator – Wikipedia

Maybe difference between HOTP and TOTP.

That part of the article is simply wrong or totally outdated.

I’m only interested in what WP writes secondarily. First of all I look at the app and its functionality itself. I recommend you just try it out and you’ll see I’m right. That article is obviously written by somebody who is not an expert on the matter. :wink:

The app does not determine the length of the secret at all, it is determined by the host to be secured.