I'm working a custom membership system in ASP.NET MVC3 (explained here). And I want to use BCrypt. My question is about BCrypt.net arguments range. i.e. the minimum and maximum length of string that BCrypt can hash it, that min/max length of salt, and also the output string's length. Really I'm creating database now, and I want to know how to set password column in db. i.e. nvarchar(256) or anything else?
The BCrypt algorithm incorporates the salt into the hash so you don't need to have 2 separate columns in your database to store the hash and the password. You may checkout this sample implementation. It produces hashes of length 60 no matter how long the plain text password is.
Related
I currently have a scenario where we are using REDIS to store string field-value pairs within a hashed set HSET.
The original reasoning behind using hashed sets instead of just sets is ease of retrieving the records using HSCAN inside a GUI Search Bar as opposed to just SCAN because it's easier to get the length of a hash to use in the COUNT field.
I read in the Redis documentation that both GET and HGET commands execute with O(1) time complexity, but a member of my team thinks that if I store all the values inside a single key then it basically returns the entire hash during HGET instead of the singular field-value that I need.
So for a made up but similar example:
I have a Redis instance with a single Hashed Set called users.
The hashed set has 150,000 field:value pairs of username:email
If when I execute hget users coolguy, is the entire hash getting returned or just the email for user coolguy?
First of all, HSET is not a hash set, it creates a hash table. The mechanism behind the hash table and set (which is indeed a hash set) in redis is the same, the difference is mainly that the hash table has values.
To answer your question:
If when I execute hget users coolguy, is the entire hash getting returned or just the email for user coolguy?
Just the email for that user. You can also use HMGET to get the emails of multiple users at once. It's O(1) for each user you fetch, or O(n) for n users.
I'm writing a script which supposed to merge some data from sql-based db. Each row has a long-integer as a primary key (incremental). I was thinking about hashing these ids so that they'll somehow 'look' like the other ids already in my RethinkDB table. What I'm trying to achive here is to avoid dups in case of an attempt to merge the same data again, but keeping the original integers as ids along with the generated ids of the data saved directly to RethinkDB's table feels weird.
Can I do that?
How does RethinkDB generate auto ids anyways?
And am I approaching this correctly..?
RethinkDB uses a string-encoding of 128 bit UUIDs (basically hashed integers).
The string format looks like this: "HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH" where every 'H' is a hexadecimal digit of the 128 bit integer. The characters 0-9 and a-f (lower case) are used.
If you want to generate such UUIDs from an existing integer, I recommend hashing the integer first. This will give you an even distribution over the whole key space (this makes sharding easier and avoids hotspots).
As a second step you have to format the hash value in a string of the format shown above. If you don't have enough digits, it's fine to leave some of the last 'H' as constant 0.
If you really want to go into the details of UUID generation, here are two links for further reading:
RFC 4122 "A Universally Unique IDentifier (UUID) URN Namespace" https://www.rfc-editor.org/rfc/rfc4122
RethinkDB's implementation of UUID generation and formatting https://github.com/rethinkdb/rethinkdb/blob/next/src/containers/uuid.cc
StandardPasswordEncoder encoder = new StandardPasswordEncoder("secret");
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
This is all clear, but in database I just store a single VARCHAR password field storing hashed value concatenated by salt? Is it that simple?
In the Database you should store the return value of endocer.encode.
just store a single VARCHAR password field storing hashed value concatenated by salt?
That is wrong (or may only not correct written), correct is:
In the first step the Salt is added to the password,
In the second step the hash is calculated (from the salted password)
hash(password+salt)
But NOT the other way around hash(password)+salt!
People say not to store passwords as plain text , but hashed passwords are still plain abracadabra text
The people mean that you should not store the password as it is (plain) but of course you can store the hash in a text representation. -- The problem that the people talk about is, that if anybody has access to the database he should not bean able to read the passwords to use them. If you think that storing passwords as hash (for example md5) is not secure enough, because of well known md5--cleartext tables, then one add a salt before, and hope that password+salt is not in that tables.
I have a column named id_num in database and the column must has a unique true value.
Users have to enter their ID Num to register in my system.
To protect ID Num, I encript it using $this->encript->encode()
The encripted data will generate different code every time I enter the same data.
Example:
First registration:
I entered 12345, will be encripted to PVfuF8GDzE4yton9tNabJwG
Second registration:
I entered the same number 12345, will be encripted to different code M0wYZsDAdR1u0WlsDAdR1
So, I call checkExistIdNum() to check either the ID Num already exist or not to make sure the id_num column is unique.
function checkExistIdNum($enc_id_num=null) {
$this->db->select('COUNT(*) AS count');
$this->db->where("(id_num = '$enc_id_num' AND user_id != '".user_id()."')");
$query = $this->db->get('user_info');
$num = $query->row()->count;
if($num>0) return true;
else return false;
}
Both has the same true value, but how can I compare id_num = '$enc_id_num' while both encripted code are different?
I think you are confusing the concept of a cryptographic hash and two way encryption.
A hash is a one way, and it always has the same result, given identical input.
MD5 or SHA1 are one-way hash algorithms that are commonly used to mask passwords in databases, the main reason for this is that it is just that, one-way, if the hash is obtained it cannot be reverted to its original value.
Use the database's built-in encryption functions so that the database indexes the values, and can quickly match against an arbitrary value you enter. Otherwise you're just reinventing the wheel, and you'll either have to keep a separate index that you compare against every time (very slow), or decrypt and compare every row individually (EXTREMELY slow).
Built-in encryption solves all of this without the possibility of leaking sensitive data through the indices.
And yeah, maybe it would be a good idea to use a hash, but for trivial account strings, that could easily be reverse-engineered if someone dumped the database.
Since you don't identify your database or your PHP version I can't be more specific.
just wondering does anyone in here have good idea about generating nice order id?
for example
832-28-394, which show a quite nice and formal order id (rather than just use an database auto increment number like ID=35).
the order id need to look random so it can not be able to guess by user.
e.g. 832-28-395 (shoudnt exist) so there will always some gap between each id.
just like the account number for your bank card?
Cheers
If you are using .NET you can use System.Guid.NewGuid()
The auto-incremented IDs are stored as integer or long integer data. One of the reasons for this is that this format is compact, saving space, including in indexes which are typically inclusive a primary key for use with joins and such.
If you wish to create a nice looking id following a particular format syntax, you'll need to manage the generation of the IDs yourself, and store these in a "regular" column not one that is auto-incremented.
I suggest you keep using "ugly looking" ids, be they auto-incremented or not, and format these value for display purposes only, using whatever format you may desire, including some format that use the values from several columns. Depending on the database system you are using you may be able to declare custom functions, at the level of the database itself, allowing you to obtain the readily formatted value with a simple query (as in
SELECT MakeAFancyId(id_field), some_other_columns, ..
FROM ...
If you cannot use some built-in or custom function at the level of SQL, you'll need to format the value supplied by SQL (an integer of sorts), into the desired format, on the client-side, using the language associated with your UI / presentation framework.
I'd create something where the first eight numbers are loosely in a pattern, and a third quartet looks random but is really a sort of checksum.
So, for example, the first eight digits increment based on the current seconds on the server clock.
The last four could be something like the sum of the first four, plus twice the sum of the second four, which will give either a two or three digit number. The final digit is calculated so that the sum of all 11 digits plus this last one is a multiple of 9.
This is slightly akin to how barcode numbers are verified. You can format the resulting 12 digits any way you want, although it is the first eight that are unique here.
Hash the clock time.
Mod by 100,000 or something.
Format with hyphens.
Check for duplicates. If found, restart.
I would suggest using a autoincrement ID in the database to link tables and as a primary key. Integer fields are always faster than string fields for indexing and well as searching.
You can have the order number field (which is for display) as a different field in the order table which will be used to display. And whenever you are planning to send a URl to a user or display a URL to the user which has order ID (which is a autoincremented number) you can encrypt it with some algorithm.
Both your purpose will be solved.
But I suggest not to make string as primary key. Though you can have a unique constraint on the order number which is going to be displayed.
Hope this helps.
Kalpak Luniya
I would suggest internally you keep the database derived primary key, which is auto-incremented.
For the visible order number, you will probably need a longer length than 8 characters, if you are using this for security.
If you are using Ruby, look at SecureRandom, which will generate sufficiently random strings to accomodate this. For example, you can use SecureRandom.hex(16), and it will give you a 16 digit hex number. I believe it can also give you base 64 strings, which will look weirder but be shorter.
Make sure this is not your only security on an order, as it may not be that hard to find a valid order number within your 8 digit code, especially if some are some sort of checksum.
For security reasons i suggest that you should use Criptographicaly secure random number generator. Think about idea on icreasing User Id length -if you have 1 million users then the probability to gues User ID in first try is 0.01 and 67 tries to increase probability over 0.5