I am building web application and have an idea to build custom authentication system, which would be quick and secure.

I do not want to use almost "default" login (email) / password combination.
I want to generate for all the users random unique cryptographically secure string key (say 70 random characters) when they sign up.

There would be only one input field to sign in, where user will have to input this key to restore his session again.

The only thing I am concerned about is its security.
What are the problems I have to cope with, using this method of authentication?

The only problem, I suspect for now is brute force. But as far as I understand, if I take any library for generating, say email recovery password tokens, the possibility of brute force will be small. Moreover from math (correct me please if I'm wrong) the chance to brute two fields of 20 characters length (like login and password) is same as one field 40 char length (my key) if they have same set of characters.

EDIT 1: I added that fact, that key should be not only random, but unique also, to make it possible to use as an ID. however I am wondering if hash, using, in ex. Bcrypt would be also unique. Is it possible to achieve that? Will the hash be unique if the key is unique? Is the risk of collision high?

  • If you were the user, how would you "remember" this 70-char secure string key? If you had a lot of users (say, 1 billion), how would you know the difference between a genuine user and an attacker who tried a random string that matched a stored key?
    – Sas3
    Jun 24 '17 at 12:56
  • Remembering is easy: provide save to file button on sign up and load file on sign in. We can also use github like copy to buffer button to make user than paste it wherever he wants. Two factor auth for security concerned users solves attacker identification problem. The aim of my idea is quick access to resource. I want to give people choice to sign up fast or add additional security measures as they wish. Thank you though, i didn't think about 2 factor auth until you asked about attack
    – Sabine
    Jun 24 '17 at 13:08

The secret key would be a (strong) password equivalent. Hence, you would need to store a hash of the password (because you do not want somebody breaking into your system getting hold of all the secret keys of your user's secret keys in one go).

Because of the requirement to hash the password, you would need some method identify which password hash you need to compare the given secret to. This is normally done by mean of a public identifier (most commonly the user's username).

So, if you extend your scheme to use some sort of public identifier (call it an ID or API-key or whatever is most appropriate in your exact use case), in addition to they cryptographically secure key, your scheme will be better (due to the stronger 'password') than your typical username-password combination.

However, this is only a single element of a secure setup: other things include the use of SSL/TLS, a good password storage hashing algorithm (BCrypt for example) a secure method to initially communicate cryptographically secure key to your user, etc etc.

  • Thank you for your extended answer, you clarified almost everything to me. The last and only thing I need to understand is importance of additional ID in case of hash. Why key hash can't be ID itself? is it because of possibility of collision between hashes? (i may have several users with same hash even if their key is unique) If so, than my idea of using only one field for auth is useless. I want to confirm that i was going to use random unique key
    – Sabine
    Jun 24 '17 at 12:44
  • I edited my question, concerning hashing and uniqueness. Take a look please
    – Sabine
    Jun 24 '17 at 13:17
  • @Sabine, You need an ID, because there is no method to match the unhashed secret to the hashed values (other than hashing it with the salt of each hash in your DB and compare the results, which is not feasible), this an important feature of storing only hashed passwords. By having some sort of unique, non-secret id, you can simply fetch the hash belonging to said id and compare it to the (newly computed) hash of the secret key; if they match, the user is authenticated. (also, if you think my answer is helpful, please upvote).
    – Jacco
    Jun 24 '17 at 14:17
  • I will mark you answer as best. But if hash is unique, you don't have to run through all the hashes and salts. Moreover if you use BCrypt, it stores salt within password, which eliminates necessity to use separate salt column. The only thing I still have to find out is how to produce unique hashes and is it possible at all. Any way your answers opened my eyes. Thank you
    – Sabine
    Jun 24 '17 at 16:35
  • Your thoughts about BCrypt is correct. However, you can't simply lookup the hash, because you don't know the hash: the user send you his secret key, you need the salt from the hash stored in your db for this user, to compute the hash of the secret key send by your user. By comparing the newly computed to the hash stored in you db. Yet, you don't know which salt to use from the secret key alone, because there is no way to know which hash belongs to the user, without some ID to identify the correct record in your database.
    – Jacco
    Jun 24 '17 at 21:28

Maybe I'm missing something, but this still feels like reinventing the wheel. As you keep adding provisions for potential issues, I feel you'll converge close to something we do use currently.

I think of authentication as this:

  • At signup, I declare that I'm X (my UserID / email); and I provide some secret (the password Y) that only you (the site) and I know.
  • When I return to login next time, I tell you that I'm X; and to prove it, I tell you the shared secret Y that we agreed upon when I signed up. Thus you accept that I'm the same X.

In security parlance we treat this as just one of the 3 common factors. You could add more factors, but I'm unable to see how we could reduce the first factor from the pair of data items (X,Y) to just one data item.

In general though, it is absolutely essential to provide completely smooth UX to users - and any attempt in that direction is laudable. For example, the way we do it in our website security app ActiFend is by

  • Not asking for registration at all (first time sign-in = registration)
  • Accepting federated authentication: Use their Google/FB/LinkedIn account and obtain the email address (only that) from there. If Google says "hey I checked this user and am accepting this user as X", that's good enough for us for this purpose.
  • For those who want another option, we send an email-based OTP, so that no need to store / save any password; complex or otherwise.

We're not the only one who's trying new ideas for this... e.g., Slack uses "magic links" (a user friendly term to depict alternate-channel authentication); Twitter and Google accept similar alt-channel auth (authenticate from another device where you're already logged in).

There are many ideas - but none of them have managed to pare down the data items to one. You might hide one of the items from the user (e.g., you could take the device ID as X; or their IP address as X.. each with their own issues), but can't avoid it altogether, I think.

I'm unable to articulate this any better... I hope this still helps.

  • Thank you for your answer. You provided so many alternatives. But I'm stick to my idea. Still your comment was very helpful. Unfortunately can't upvote it
    – Sabine
    Jun 24 '17 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.