Here is my simple table definition for a mysql credentials table.
case "credentials":
self::create('credentials', 'identifier INT NOT NULL AUTO_INCREMENT, flname VARCHAR(60), email VARCHAR(32), pass VARCHAR(40), PRIMARY KEY(identifier)');
break;
Please ignore all but the inner arguments...the syntax is good...I just want to verify the form. Basically, I have an auto-incrementing int for the PRIMARY KEY and 3 fields - the users's name, email, and password.
I want this to be as simple as possible. Searches will be based upon the id
Question: Will this work for a basic credentials table?
Please please please do not store passwords in plaintext.
Use a well known iterated hashing function, such as bcrypt or PBKDF2. Don't store a raw MD5 hash, or even a raw SHA or SHA-2 hash. You should always salt and iterate your hashes to be secure.
You'll need one extra column to store the salt, and if you want to be flexible you could also have per-user iteration counts and maybe even per-user hash functions. That gives you the flexibility to change to a different hash function in the future without requiring all users to immediately change their passwords.
Apart from that the table looks fine.
I would suggest that you increase the size of the email field (maximum length of an email can be up to 256 chars). Also you should store your passwords as a hash (e.g. bcrypt) not a plain string.
Related
In my DynamoDB table named users, I need a unique identifier, which is easy for users to remember.
In a RDBMS I can use auto increment id to meet the requirement.
As there is no way to have auto increment id in DynamoDB, is there a way to meet this requirement?
If I keep last used id in another table (lastIdTable) retrieve it before adding new document, increment that number and save updated numbers in both tables (lastIdTable and users), that will be very inefficient.
UPDATE
Please note that there's no way of using an existing attribute or getting users input for this purpose.
Since it seems you must create a memorable userId without any information about the user, I’d recommend that you create a random phrase of 2-4 simple words from a standard dictionary.
For example, you might generate the phrase correct horse battery staple. (I know this is a userId and not a password, but the memorability consideration still applies.)
Whether you use a random number (which has similar memorability to a sequential number) or a random phrase (which I think is much more memorable), you will need to do a conditional write with the condition that the ID does not already exist, and if it does exist, you should generate a new ID and try again.
email address seems the best choice...
Either as a partition key, or use a GUID as the partition key and have a Global Secondary Index over email address.
Or as Matthew suggested in a comment, let the users pick a user name.
Docker container naming strategy might give you some idea. https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go
It will result in unique (limited) yet human friendly
Examples
awesome_einstein
nasty_weinstein
perv_epstein
A similar one: https://github.com/jjmontesl/codenamize
I'm new to password_hash and password_verify, and they appear to be the most efficient way of storing passwords securely!
I noticed that password_hash produces different hash for the same plain-text value every time!
This means that if a user tried to create an account with the password (thisIsMyPassword) it will generate a hash like this $2y$10$VCNH8ndve8hwbvLJ2nMHtOsEiigE4zA7ViADxCJfq9bmUCmkNkcce,
And if another or the same user tried to create another account with the same password i.e. (thisIsMyPassword) the account will be created and the hash value of the password will be something like $2y$10$Hqssc5nn3pzgfwqVwQrQz.Ny71q972RXmCmyV9ykywG8iELbsf47a!
Now you see the same value i.e. (thisIsMyPassword) resulted in different hashes!
Is this OK?
Is it OK to let the users use same passwords, as long as the password hash is different in the database?
The password hash includes a so-called salt, a small random value, which is here to prevent dictionary attacks, here is what PHP manual says:
If omitted, a random salt will be generated by password_hash()
for each password hashed. This is the intended mode of operation.
The value you get as the output, is not really a plain hash, but a
string made of - algorithm id, salt and HASH(password,salt).
The used algorithm, cost and salt are returned as part of the hash.
Therefore, all information that's needed to verify the hash is included.
in it. This allows the password_verify() function to verify the hash
without needing separate storage for the salt or algorithm information.
consider (for an example) that we have encrypted a file (sample.txt) using win-zip 9 by typing a password "agoodpassword".
now if we try to open the file by typing some wrong password, we get a error message saying: the password typed is incorrect.
the question:
how can a software verify if the password typed in is correct or not? the content of the file could be any random data, so checking for errors in the file after decryption is not going to work. But still the software needs some source to verify this password; so how does this win-zip software verify if the decryption is successful or not?
What I suspect is the password could also be there in the same file being encrypted. Is it true or does the software adopt any other method?
Instead of just encrypting, many applications that create a ciphertext also create an authentication tag. This authentication tag can be checked before decryption; if the authentication tag is incorrect than one of the parameters (key, IV or ciphertext) is incorrect.
To use encryption using a password it is common to utilize PKCS#5 (password based encryption). PKCS#5 contains a password hashing method that utilizes "key stretching", making it harder for an attacker to test/compare many passwords using brute force or dictionary attacks. Such a password hashing method is called a Password Based Key Derivation Function or PBKDF. The latest PKCS#5 describes PBKDF2.
Now if you want to create a new password based encryption method, I would propose to do the following:
Perform a PBKDF2 with (very) high iteration count and 128 bit salt;
Make sure that the user gets feedback about the strength of the password;
Perform a KBKDF (key based key derivation function) on the result of PBKDF2, creating a check value, a data encryption key, and a data authentication key;
Use the data encryption key for an encryption method, say AES-128-CBC with random IV;
Use the data authentication key for a HMAC over the IV and the ciphertext;
Store the check value;
To verify the correct password during decryption, use the check value.
Note that I did not discuss the KBKDF yet. You may use a hash over the output of the PBKDF2 and a simple counter or string for that, say SHA-256(key seed, "ENC").
You can use a hash value to provide a very high probability that anything other than the correct password will be rejected. Basically, if you hash a password it produces a number with a certain number of binary digits, and a good cryptographic hash will produce a completely different number (in as much as random thing tend to differ) if you type something even the tiniest bit different (for example, changing the order of two characters, or using uppercase instead of lower).
There's still a very small chance that two different passwords will produce the same hash value... for example if you only had a 32-bit hash value then there's about a 1 in 2^32 (4 billion) chance. It gets quite mathematically complex to create a hash function that doesn't let you retrieve the password (especially if it is a short password, and someone can pre-generate a list of short words with specific hash values too), so you probably want to have a pretty weak hash - just good enough to avoid returning corrupt data for 99.99% of typos - and/or one that's known to be resistant to such attacks.
I posted a similar question over on the Adobe Community forums, but it was suggested to ask over here as well.
I'm trying to cache distinct queries associated with a particular database, and need to be able to flush all of the queries for that database while leaving other cached queries intact. So I figured I'd take advantage of ColdFusion's ehcache capabilities. I created a specific cache region to use for queries from this particular database, so I can use cacheRemoveAll(myRegionName) to flush those stored queries.
Since I need each distinct query to be cached and retrievable easily, I figured I'd hash the query parameters into a unique string that I would use for the cache key for each query. Here's the approach I've tried so far:
Create a Struct containing key value pairs of the parameters (parameter name, parameter value).
Convert the Struct to a String using SerializeJSON().
Hash the String using Hash().
Does this approach make sense? I'm wondering how others have approached cache key generation. Also, is the "MD5" algorithm adequate for this purpose, and will it guarantee unique key generation, or do I need to use "SHA"?
UPDATE: use cacheRegion attribute introduced in CF10!
http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7fae.html
Then all you need to do is to specify cachedAfter or cachedWithin, and forget about how to to generate unique keys. CF will do it for you by 'hashing':
query "Name"
SQL statement
Datasource
Username and
password
DBTYPE
reference: http://www.coldfusionmuse.com/index.cfm/2010/9/19/safe.caching
I think this would be the easiest, unless you really need to fetch a specific query by a key, then u can feed your own hash using cacheID, another new attribute introduced in CF10.
I have a multiplayer mobile game out in the wild, it's backed by a sql database. Each game gets an ID which is just an auto-increment field. I can look up a game with a url like:
http://www.example.com/gameId=123
That url is not visible to players at the moment, but I was thinking of displaying it so users can invite friends and let non-players look on in the game as they play (through a browser - at the moment everyone plays through a native app).
But the fact that I'm putting the game ID out there in the open seems like a bad idea. If someone guessed an endpoint for say deleting a game, they could do bad stuff knowing the ID (of course my endpoints are protected by user auth, but still).
Do most services mask IDs of this sort, should I send out a url like:
http://www.example.com/gameId=maskedIdAbc
and then my game server has to translate that ID into the corresponding ID in my database?
Not sure if that's overkill. If not, what's a good way to generate a unique alpha-numeric string based off a unique integer?
Thanks
Why not change the primary key of the game from an incremental ID to a GUID? The game is out in the wild but you should be able to get there in a number of steps. Add the Guid as a Field and allow games to be looked up either by ID or GUID. Update your clients to use the GUID, phase out the ID, and finally change the primary key to be the GUID.
You could hash the int, or even use the hex, but its breakable. Better to implement a complete fix, if you don't want to use a GUID you could implement your equivalent random characters that you store against each db record but why go to the trouble when GUIDs are usually Nativity supported by databases.
If range of the integers is not big, you may define tabble with unique, random alpha-num strings. I think it's the best way.
I has a similar situation and did not want to use the gameID (using your example here) in the url, as someone can use any number. I can still use the ID's, but need to add additional checking for authorizing the users.
You could use UUID to generate gameID's but I see few problems with this;
- non numeric ID will have an impact on the performance
- if this is the primary key and want to use it as FK on other tables, space
What I did;
In addition to gameID in my table, I added another column WebGameID varchar (32). After the game ID was generated, updated the WebGameID = MD5(gameID). This will be a unique 32 char string for the specific gameID. With this I was able to use gameID for internal keys and FK's ad only use WebGameID for the URL for limiting user manipulation.