Online secure databank for usernames and their passwords?

Hello Java-Gaming,

Fundamentum, my game I am working on is a multiplayer game. But the main thing you need for a multiplayer game is a online databank that is secure, safe and can’t be hacked. But I am like searching 3 hours to find how to make an online secure databank. Only found some video’s with offline/create a document on your own PC/not accesable from other PC’s.

Or maybe I am thinking wrong, maybe the databank needs to be on your own website?

But the question is still the same: Does anyone have a tutorial/link/something about online secure databanks? Maybe you wanted to make it also on a day and you still got/know the link of the site.

This will really help my out and I will thank evryone so much for bringing me closer to the databank!
-Roseslayer.

There are a lot of things you can do to secure an online database - you’ll probably be fine with just doing the basics - which is to hash and salt user passwords, and avoid saving (explicitly) and non-password encrypted data personal data (like e-mails and bank cards - emails might be too excessive, but if you don’t need the arbitrary access than you should encrypt them and prompt the users for a key generated via their password.)

That said, the games platform you are deploying your games on should provide you with some user sensitive cloud accesses that you can use instead. GameJolt provides an API you can use to access a user-sensitive cloud.

If you want to write your own server, the database will sit on the end of the server and should only be accessible locally (with respect to the server). At that point, you need to make sure that you use standard database configurations (i.e. database only accessible via localhost, long password etc…) and make sure your server doesn’t open up any loop holes, using precompiled SQL statements etc.

Here is how i do it:

I create a MySQL Database** on the server where my game server is running. Where i store hashed password (sha1, bcrypt, …)

Workflow:
[Client]

  • User enters username & password
  • Username and hashed password are send to the server
    [Server]
  • Receives username & hashed password
  • Server finds the username in the database an checks if the hashed password in the database matches with the one received from the client *
  • Server sends client an “OK, GO” & a session token.

Every further communication between client & server must pass token verification(clientToken == serverTokenForThisClientID)

To further secure this you should use SSL to encrypt the connection.

  • This can be done over an API (i.e. verify.php?pass=$somehash&user=Herp ) if you don’t want any mysql connections in your java code (where you would have to hardcode the password in)
    ** As secure as the server it resides on & the passwords/methods you chose for accessing it (I.e. prevent mysql injections, limit login attempts, …)

I just want to make a point out of also salting the passwords before hashing them - otherwise they can be looked up in a rainbow table. This would make a simple password like loljeremy into lol!~jjE#@rM%8^*y which would make it much less likely to be contained in a rainbow table.

Just make sure you don’t expose the database to user.
DB <-> server <-> client
and follow Jeremy’s for the rest.

For more advance stuff (depends on your DB), you can utilize role restriction, view manager, and so on.

The times that hashing with salts being a barrier to crackers are long since gone. Rainbow tables are equally outdated. These days GPUs and software are so adept at bruteforcing billions of passwords per second, in patterns that most humans use, that even a fair amount of 10 character passwords are now ‘reversable’ within a few hours. The Linkedin leak of 6 million hash-salted passwords showed how weak this approach actually was. Within a day 95% of the passwords were revealed, including passwords with length up to 14 chars.

The problem is that hashing algorithms are designed to be fast. This makes them vulnerable to intelligent bruteforcing attacks, going through all permutations of substituting certain characters with numbers, assuming passwords typically starting with an uppercase character and ending with one or 2 digits or 4 (in the range 1900…2000) and special characters. That, combined with word lists and lists of previously found passwords.

You should make sure that calculating the salted-hash takes about 1s on modern hardware, so when using hashes like SHA1 (instead of bcrypt) that means:


// laughable
passhash = hash(hash(password) +"::"+ hash(usersalt)));

// practically uncrackable
temp = hash(hash(password) +"::"+ hash(usersalt)));
for(int i=0; i<100000; i++) {
  temp = hash(hash(temp) +"::"+ hash(i)));
}
passhash = temp;

Luckily this hashing happens clientside, so it won’t grind your server to a halt.

A good short read: http://codahale.com/how-to-safely-store-a-password/
(note that we added the work-factor in the hash approach)

A good long read: http://arstechnica.com/security/2013/05/how-crackers-make-minced-meat-out-of-your-passwords/
(on how a password like qeadzcwrsfxv1331 and 98% of other ‘hard’ passwords are cracked)

Login
Logging in by sending your passhash is susceptible for man-in-the-middle attacks (even when using SSL). You should use a hash-handshake, so that a login cannot be played back later. In practical terms the server generates a random string of chars, and asks the users: what should be the hashpass if you were too take the hash of it and this piece of data.


// Server sends to client:
String challenge = generateRandomString(1024 /*length*/);
String salt = // retrieve from database

// Client sends to server:
String saltedpasshash = hash(hash(salt) +"::"+ passhash);
String answer = hash(saltedpasshash +"::"+ hash(challenge));

// Server verifies answer

Access
As for access tokens (or cookies providing session-ids) you have to guard against stealing such tokens. It’s much better to calculate nonces, so that every request to the server has a unique access token, that only the server and client can calculate, This sequence of access tokens should be consecutive, and once the server receives 1 access token it wasn’t expecting, it should logout the user immediately. These sessions should not be undefinitely valid. Creating a new session about every hour is advisable.


nonce = hash(
   hash(loginChallenge) +"::"+
   hash(passhash) +"::"+
   hash(requestCounter++)
);

@Riven

Hashes appropriate for user passwords are designed to be slow, not fast.

Salting is pointless if it isn’t done properly, but if done properly it can definitely prevent a lookup in a rainbow table. I.e, salts should not be consistent and should be generated. If your salts are large (and you put limitations on the password - i.e length and use of special characters or non-ascii character) they definitely have an effect on securing the password. If your salts are not randomly generated than yes - they are pointless since one crack (that is not a result of a collision) opens the door to all other passwords in the database. Otherwise - you face the same obstacle for every password in the database which would take a very long time to compute.

I am not saying hashes secure your password 100% - what I am saying is giving your users that grace period after the database has been hacked and providing them with time to accommodate for the breach is essential. Not salting them makes it much easier for passwords to be stolen.

I honestly don’t believe any rainbow table out there will have a sufficient number of lookups for your salted password hashes.

Having a unique salt per user doesn’t help anything if the hash function is fast (like with commonly used MD5,SHA1,SHA2). Linkedin passwords had unique salts per user and that didn’t stop anybody. As said, rainbowtables are so outdated they shouldn’t even be mentioned anymore. Nobody taking cracking passwords seriously uses them.

How not? Rainbow tables are the essence to cracking hashes - other than collisions which are pointless because they don’t guarantee the original data - how are they not relevant? I’m going to make something up to illustrate.

You say that hashes today are essentially brute-forced (using algorithms that don’t do so randomly but choose likely combinations that would be a password). A rainbow table is essentially a database of this that can be looked into - and they are usually constructed before\during attacks so the data doesn’t take months to access after the breach after it is announced (and so that you don’t waste time computing hashes you’ve already calculated) to the users (by then the users would’ve had the time to change their personal data) - EXCEPT:

You cannot generate a rainbow table if the SALT is not predictable. They can be quickly created after an attack only if the salt is not unique on a per user basis - further it is impossible to generate a rainbow table (even after you have cracked one hash to determine it’s salted) if the passwords are salted on a per-user basis.

A better example is credit cards where hashes are definitely not useless (or any particularly formatted field)

Consider a credit card would take the format of:
XXXX-XXXX-XXXX-XXXX
We know that 'X’s is a number. How long do you think it would take to create a rainbow table for that? Maybe a while - but it we started 20 years ago? Passwords are like that but more complicated - like you a argued though, there is a fixed pattern to most passwords that can be predicted so this example really isn’t too far from that.

Now how long do you think it would take to create a directory table to (lets assume a fixed salt)
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnXXXX-XXXX-XXXX-XXXX
Where n can be any printable character?

They were. Not any longer. Rainbow tables are too big, the disk I/O of building and plowing through gigabytes and even terrabytes of data is so slow that bruteforcing it is faster, not to mention that you quickly run out of diskspace, regardless of the amount of harddisks you throw at it. When bruteforcing it you can reach dozens of giga-hashes per second on a single, cheap desktop computer - that’s hundreds of GB/sec of generated data. Writing this to disk is impossible. Argueing that this only needs to be done once doesn’t hold any merit, now that we have salted passwords.

Rainbow tables equally can’t handle uniquely salted hashes, while with bruteforcing it’s trivial to incorporate any scheme that yielded the hashes. Keep in mind that the unique salt for every user is known, after somebody compromised the ‘user table’, as this contains [username,salt,saltedpasshash].

Everybody has moved on to bruteforcing, because that’s so much more effective. There’s is no point argueing this. Look around, and you’ll observe that everybody taking cracking seriously, ditched rainbow tables in favor of running the code on a (cheap) GPU.

[quote=“Jeremy,post:9,topic:43396”]
[nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn] is known (whether or not it is a fixed or unique salt per record), incorporated in the bruteforce code, so doesn’t provide any security, just a minor slowdown of, say, factor 2.
[XXXX-XXXX-XXXX-XXXX] is not anything like a password, so the password cracking strategies do not apply here. Cracking hashes of >12 bytes of purely random data is still infeasible. Luckily for crackers, passwords are anything but random.

I advice you to read the ArsTechnica article I posted. It explains it nicely.

It is definitely applicable (the credit-card example) - like a credit card, user passwords have a predictable pattern - it is much more complex with user passwords but that was my point.

First of all, on IO speeds: Looking up a hash will always be much more efficient than brute-forcing a hash. Data can be hashed in a solid state device to vastly improve look-up times.

Second of all, I think you have a misunderstanding on the attack procedure. No sane cracking algorithm would discard a hash\key pair because it doesn’t match the current password being trying to be cracked - instead it would be stored in a directory and looked up (probably by a much lower priority thread since hashing\lookup have a vast different on the required CPU time) i.e, a rainbow table - and discarded when they are no longer used. Otherwise your hashing thread will cycle through hashes it’s calculated X times before when trying to brute-force a different password for the Xths time. How many hashes do you think can be looked up in the one second the CPU spends calculating a hash? That’s why we use rainbow tables (or rather, a table of temporary hash\value pairs.)

Yes universal rainbow tables are garbage and they need to be generated while attacking rather before attacking - because of per-user salts. Otherwise, they are definitely worth their memory.

Yes, cracking hashes requires a lot of processing time, and fast cache IO - but that is how they’re designed to work.

[quote=“Jeremy,post:11,topic:43396”]
No. It seems you don’t get a sense of the data size we’re talking about. Calculating data is often much faster than storing it first, then retreiving it - even if you store it only once - which, again, is not possible with salted hashes.

[quote=“Jeremy,post:11,topic:43396”]
Again: no. Storing it on disk is such a slowdown that it doesn’t make any sense whatsoever.

[quote=“Jeremy,post:11,topic:43396”]
I seriously advice you to look around and see how everybody ditched them years ago. There’s really no point arguing it.

I didn’t say on disk, I said an IO cache. There are tons of very quick IO devices… SSD drives for example - and depending on how many threads you had doing a look-up, you may only need so many in the cache at a time (and you can then have another low-priority thread discarding known unused hash values from the SSD and moving a new hash\value pair into memory.

I have read the article and all it says is “bycrypt bycrypt bcrypt - salts are pointless” - but the reality is that they are widely used throughout the industry - and it is because they are effective.

EDIT

Also, I was re-reading your post - I doubt even super computers can perform ‘billions’ of proper, password appropriate hashes in a single second. There is definitely no GPU that can do it - otherwise we have some serious security issues we need to start considering.

SSD drives? Laughable.

Let’s say we have an 8 character password, and use 80 chars out of the possible 256.
That’s 80^8 = 1677721600000000 hashes
Every SHA1 hash takes 20 bytes to store. (I’m ignoring that you’d also have to store the input strings for every hash)
That’s 30518 TB (30 PB).
Take a fast SSD (1GB/sec)
It would take 1447 days (almost 4 years) to serialize.
Repeat the process for every salt. (!)
With 500GB SSDs costing about $300, you’d have to spend $18,310,800 on drives alone.

And then… you’ve only dealt with 8 char passwords.

With a small cluster of GPUs setting you back a few thousand dollar, you’d work your way through it in a few hours.

[quote]The clustered GPUs clocked impressive speeds against more sturdy hashing algorithms as well, including MD5 (180 billion attempts per second, 63 billion/second for SHA1 and 20 billion/second for passwords hashed using the LM algorithm.
[/quote]

You clearly missed the point of the article, it even discusses how salts are a requirement for bcrypt.

I guess I’ll leave it here. I just can’t believe how you stick to your guns when it’s so obvious that everybody moved away from rainbow tables.

I think you’ll also find the irony that bcrypt inherently incorporates a salt also laughable:

Like I said, any cachable IO devices - even RAM would count (whats the datarate between the GPU and system memory?)

Rainbow tables are pointless because of salts - that is why it is important that you SALT your data.

Accessing a CACHE doesn’t have to be fast, just faster than performing the actual hashing algorithm. 1GB/Sec seems more than appropriate to me. Since IO operations are usually performed outside of the control of a thread - an interrupt would be raised when the data is ready and you would lose virtually no time waiting on this data to arrive.

Caches only work if you have ‘hot data’, which mean you can have staggered storage levels, where each level has a specifically chosen tradeoff between cost/byte and cost/bandwidth. That doesn’t apply to rainbow tables, which are 100% random access, all the time.

[quote=“Jeremy,post:15,topic:43396”]
Sure, but that is not enuogh, because while it effectively stops rainbow tables, it doesn’t stop bruteforcing. That’s what the whole discussion is about.

I promised to ‘leave it here’ - I couldn’t resist. Bye now! :point:

A rainbow table is a dictionary of hash values and their respective keys - there is nothing dictating that this has to be stored in ‘hot data’

A cache works outside and inside of hot data - a cache by definition is a temporary storage medium that offers a quicker look-up time than reloading\calculating data.

Reducing an attack to brute-forcing IS ENOUGH, and its all we can do.

I’ll leave it at this:
You cannot possibly argue against salts and than argue for bcrypt since bcrypt is an hashing algorithm which inherently implements a salt. You argument makes no sense.

Doesn’t this essentially convert the passhash into a password which is stored in the database in plaintext? If you’ve got an intelligent client, why not use SRP?

It’s a login-challenge: it’s transient, and expires quickly and is immediately invalidated when it receives an incorrect answer. It’s basically saying: any client that can come up with the answer to our challenge within a reasonable timeframe, is allowed in. For a client to know this answer, it has to know the passhash (and therefore likely the password) and the challenge token. If you happen to know both (and obviously the username) – well, welcome in!

All my example code and discussion of bcrypt involved the usage of salts. I never argued against them :-X