I understand that if we just hash a password, a hacker could use a pre calculated hashed password table and compare it to the actual hashed password table. From what I understand if we add a random string as a salt before hashing, the pre calculated hash table won't work.
Now my question is, suppose a users password is "password", I add 999 to it and hash the string "password999" before saving it. Now when the user returns to my site, how do I know that I need to add 999 to his password before it is compared to the hashed values in the database? Do I maintain a separate table with all the salts for every username?
You need to store the salt for each user in a separate column next to the password.
Related
I need to store some user data in one server database. It is not sensitive data, but neither I or other users should get access to this content. I want the owner to be confident that even I or other developers will not be able to read his data querying the database.
Tables structure will be like this: (ID | Data) where Data should contain an encrypted JSON string.
I would like to do encryption/decryption on the client, using a secret key that would not persisted anywhere (user should keep this password or otherwise he would not be able to get his data anymore).
Do you see any pitfall in this approach?
Based on my research the purpose of a salt is to defeat the use of a rainbow table. This is done because rainbow tables are only created to look up hashes of a sole password(without a salt). I am having a conflict understanding how we can't use rainbow tables in when salts are introduced. Suppose we have the following scenario:
I am a malicious hacker and I want to gain access to a rich person's bank account. I am able to gain access to the bank's database which has the salt and the hashed string in plain sight, which is a function of the user's password and salt (f(password + salt)). The salt is fsd88. Next I get a rainbow table from some hacker on the web. Great, so I am all ready to become rich and move to Switzerland.
What I do next is I take the the hashed string and look it up on the rainbow table (according to a tutorial online this takes about an hour to do). The rainbow table look up then returns passwfsd88. Since I know the salt is fsd88. I now know what the password is! It's passw!
What is wrong with my mental model of a salt? Thanks for reading.
The salt is added before the hash is calculated:
$password = 'secret';
$salt = 'kU832hNWQ2122093uiue';
$passwordHash = hash($password + $salt);
In this example not the hash of password 'secret' was calculated, instead it is the hash of 'secretkU832hNWQ2122093uiue'. Nobody will ever create a rainbowtable with such passwords, if you find a precalculated rainbow-table it would contain the hash of 'secret'.
Of course you can build a rainbow-table with a list of possible passwords with this salt (the salt is not secret), but if each password got its unique salt, then you would have to build rainbow-tables for each password separately. That means, the salt prevents to use a single rainbow-table to get all passwords at once.
Good to know that i'm rich now, regards from switzerland :-)
Just a quick question on the best practise for the below case.
Developing a website with accounts. Website is setup so that no two accounts can have the same username i.e. all usernames are unique.
When persisting accounts in a database, is it ok to use the username as a primary key (unique identifier) or is there some reasons I should be aware of that would require a separately generated unique id?
Don't use username as primary key, never.
Use surrogate keys (ie autogenerated numbers), because
they are faster and smaller (key is 4-8 bytes, username is up to you dont know bytes?)
it is only right now you suppose usernames will be unique, later you will find out that you need non-unique usernames (for example for deleted users for which you have to save transaction history), or requirments will change
users should be able to change their username, in case of error/typo/etc
UPDATE: in case of distributed systems, use GUIDs
Hey guys I have a simple database question. Say I am emulating a university login system.
If i have a student table and faculty table, can I just store the password directly in the corresponding table? For example student table has such attributes as (student_ID - primary key), First_name, Last_name, Classification, and now I would add a password field.
If I create a login table i'm just effectively copying over thousands of potential records. Is there any benefit to creating a login table with say (primary key STUDENT_ID,FACULTY_ID) and a password field for authentication purposes?
Can I increase security on just one table? What is the better approach?
As one student contains only one password, there maintains one to one relationship so there is no need of splitting the table for one to one relationship.
If there is one to many relation, breaking the table will be good such as for storing multiple phone numbers or multiple address of a user.....
You need to decide upon whether only students will be allowed to login into your system.
What about admin user, teachers, etc?
even if there is a remote possibility that a non student will log into the system it is advisable to create a login table with userid and password stored in MD5 encryption
I have different 3 types of users and each type of user can have columns and relationships with tables that another type doesn't, but all of them have login(Unique) and password,
how would you do:
create a table for each type or
create one table for all of them or
create a table for all of them only for login and password and separate for all the other things and bind them with a FK
something else
Number 3 is the best of the options you suggested (updated slightly for clarification):
create a table for all of them for login and password and anything else that is shared and a separate table for all the other things that are not shared and bind them with a FK
Except don't store the password, store a hashed version of a salted password.
An alternative might be to assign groups and/or roles to your users. This might be more flexible than a fixed table structure, allowing you to add new roles dynamically. But it depends on your needs whether this is useful for you or not.
As Aaronaught pointed out, in the main table you need an AccountType to ensure that a user can only have one of the roles. You must remember to check the value of this column when joining the tables to ensure that a user has only one role active.
A unique constraint on the foreign key ensures that a user can only have a role once.