BrandonPotter / GoogleAuthenticator

Simple, easy to use server-side two-factor authentication library for .NET that works with Google Authenticator and Authy.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unsafe secret generation

RobThree opened this issue · comments

As per your README:

string key = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);

GUIDs are designed to be unique, not random. So this is NOT a good idea. The code should be any BASE32 string (2-9, A-Z, excluding O/L), however your method only produces (0-9, A-F). You're losing half the possible values.

Also, you're using only 10 characters, 80 bits. As per RFC4226:

R6 - The algorithm MUST use a strong shared secret. The length of the shared secret MUST be at least 128 bits. This document RECOMMENDs a shared secret length of 160 bits.

So you're also dropping another 80 bits of entropy there (half(!) of the recommended). This makes the secret MUCH easier to guess / brute force if one or a few "PINs" are known. Your method only uses 25% of the available entropy by my calculations.

commented

Shown as example for illustration purposes only. Developer is expected to have experience and understand best practices of key generation, which is not handled by the library.

Thanks for your interest!

The problem with examples is that people tend to copy and paste them. Especially assuming people 'to have experience and understand best practices of key generation'; there's lots of inexperienced people, some just don't know any better. People may assume the provided code is safe. People may assume the library 'handles' it or people may assume it's good enough.

At the very least a warning would be advisable. But better yet, why not simply provide good (or at least better) code from the get go that is usable for real life usage?

Especially since you already have an overload that takes a byte[] for a key, why not use this in your Readme?

using System.Security.Cryptography;

string key = RandomNumberGenerator.GetBytes(20);

This provides the recommended amount of bits of entropy and is cryptographically secure. And so much better than:

string key = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);

It's even shorter and more readable too! 😉 And it doesn't suggest to use a Guid for 'randomness' since, as I said: GUIDs are designed to be unique, not random