I have done some research on encryption and learnt how it works and what it consists of but I'm yet to fully understand how to implement password encryption.
I'm trying to encrypt my passwords that are being sent to my database, how can I achieve this?
Thanks to the information you guys provided I have had a look at hash tables, am I correct in assuming a hash table basically converts a value to a different value for example:
var HashTable = { one: [1,10,5], two: [2], three: [3, 30, 300] }
and then passes the new value to the database?
Do not encrypt passwords, when the attacker gets the DB he will also get the encryption key.
Just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iIterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use a function such as PBKDF2, Rfc2898DeriveBytes, password_hash, Bcrypt or similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force.
Cryptographic hash functions are substantially more sophisticated than the example in the question, their output can not be distinguished from random bits/bytes, a one bit change on the input essentially causes 50% or the output bits to change and they are not reversible.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last year.
Improve this question
I need to store a hash of a single password in a .Net WinForms application.
What's the most secure way to do this?
In particular:
Salt, HMAC, or both?
How much salt?
How many iterations?
What encoding? (The password is plain ASCII)
I assume that the algorithm should be either SHA512 or HMACSHA512.
Salt your hash with secure random salt of at least 128bits or longer, to avoid a rainbow attack and use BCrypt, PBKDF2 or scrypt. PBKDF2 comes with NIST approval.
To quote: Archive.org: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
The problem is that MD5 is fast. So are its modern competitors, like
SHA1 and SHA256. Speed is a design
goal of a modern secure hash, because
hashes are a building block of almost
every cryptosystem, and usually get
demand-executed on a per-packet or
per-message basis.
Speed is exactly what you don’t want in a password hash function.
Fast password validation functions are a problem, cause they can be attacked using brute force. With all the algorithms above you can control the "slowness"
I can recommend BCrypt.net. Very easy to use and you can tune how long it will take to do the hashing, which is awesome!
// Pass a logRounds parameter to GenerateSalt to explicitly specify the
// amount of resources required to check the password. The work factor
// increases exponentially, so each increment is twice as much work. If
// omitted, a default of 10 is used.
string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
// Check the password.
bool matches = BCrypt.CheckPassword(candidate, hashed);
For a server-side implementation with a large number of passwords, you should definitely use a tunable iterated approach like bcrypt. This well-known article on the topic is still (mostly) relevant:
http://www.securityfocus.com/blogs/262
For a single password in a stand-alone application, where the storage location is probably already secured by the system's own authentication system, I think it's much less important. A single strong hash is likely good enough, and adding salt is easy enough that there's no reason not to do so.
RNGCryptoServiceProvider to generate a random salt, then SHA512 the password with the salt, and finally store both the password hash and the corresponding salt if you want to later verify that some text equals the stored password.
Hash and Salt. If you only hash you could be attacked by a rainbow attack (reverse has lookup) and a salt makes this much more difficult (random salt would be best.) For your encoding you will probably want to either Base64 or Hex encode your resulting byte array. If you just try to store the byte array as Unicode you could run the risk of some data being lost because not all patterns are valid characters. This also allows for an easier way to compare hashes (just compare the base64 or hex string when you want to validate instead of comparing the byte array)
An increased number of rounds doesn't do much beyond slowing down would be attackers. But is also makes is much more difficult to reuse the hashes in the future if you lose or need to recreate your hash algorithm. You might check out a standard password hash such as crypt on unix systems. This allows for you to change out the hash algorithm and can even support versioning.
But again, a simple hash + salt is good enough for most applications.
Strictly looking at more secure:
Salt, HMAC, or both?
Both would be more secure. Since the key to the HMAC could be considered a salt, doing both would be a little redundant, but still more secure because it would take more work to crack.
How much salt?
Every bit of salt would double the combinations that would need to be maintained in a rainbow-table to easily crack the password. But since there is only one password, and only one salt, more may not be needed. The HMAC uses the block size of the underlying hash for its key size, 1024 bits for SHA512. The block size should be good enough for the salt, but doubling or tripling it would make cracking the password with a rainbow-table much, much harder.
How many iterations?
The more the better. Sure, more iterations means it will take longer to determine if the correct password was entered, but computers are fast and users will not mind waiting for a few seconds while verifying the password. Doing more iterations would mean that someone cracking the password would have to do more iterations too.
What encoding? (The password is plain ASCII)
Might as well encrypt (with AES) the over-iterated, over-salted, HMAC'ed, super-secure password along with its salt just to make it harder. Make the password for the encrypted password hash and key, be some combination of strings that should appear in the executable such as "RNGCryptoServiceProvider" or "System.Security.Cryptography". And while encoding we might as well convert it hex, or base64, or better yet base-36 or some other less expected conversion.
Note: This was mostly written in jest, but should still contain some truth.
I think you should stick with open standards. Among the current hash schemes, the "{ssha}" used by OpenLDAP is very secure and widely used. You can find the description here,
http://www.openldap.org/faq/data/cache/347.html
Most LDAP libraries implement this scheme.
You could follow a published standard, like pkcs#5. see http://en.wikipedia.org/wiki/PKCS for a short description, or https://www.rfc-editor.org/rfc/rfc2898 for the RFC.
Here is an API which will do everything you need/want :)
https://sourceforge.net/projects/pwdtknet
I am encrypting objects using Node.js native crypto methods like createCipherIv.
const algorithm = "aes256";
const inputEncoding = "utf8";
const outputEncoding = "hex";
const iv = randomBytes(16);
export async function encryptObject(dataToEncrypt: object, key: Buffer) {
const clear = JSON.stringify(dataToEncrypt);
const cipher = createCipheriv(algorithm, key, iv);
let ciphered = cipher.update(clear, inputEncoding, outputEncoding);
ciphered += cipher.final(outputEncoding);
return iv.toString(outputEncoding) + ":" + ciphered;
}
Sometimes I am encrypting the same object multiple times and send it over http(s). That makes me think a man in the middle could observe that communication and maybe gain information about my user by using something like a Rainbow table to map the encrypted Data to real data over time.
Now I'm not sure if my worries make sense, but I'm thinking, that my encryption could be more secure if a add a salt to it. So far I've only come accross salt when hashing, not encrypting. Hashing is not an option for me, because I cannot rely on hashes to be equivalent. I actually have to do something with the data, so I have to be able to decrypt it again.
So my questions are:
Do my thoughts add up, and I would be better of adding salt?
Is it possible to use Node.js native crypto functions for symmetric encryption while adding salt to the mechanism in order to have different encrypted results on every run?
Basically the IV is your salt. That's it purpose (apart from initializing the chaining algorithm). So you are ok with the code you posted here. Initialization vector is random so the encrypted bytes will be different every time.
Just check it with the simple console.log you will see that resulting bytes are totally different every time.
On the other hand I don't think that this (identical encrypted bytes) is much of a concern here. I would make rather sure that the chaining method is at least CBC. Here you can read more about it:
https://en.m.wikipedia.org/wiki/Block_cipher_mode_of_operation
Also if you want to be super secure with the man in the middle attack. You can add some HMAC to your message. This will ensure that no one can flip a bit in your message to make it different. In other words it provides
data integrity and authenticity of a message.
But still if you send data over httpS, all of those safety measures are already in place. Hence the name of the examplary https cipher:
tls_dhe_rsa_with_aes_256_gcm_sha384. Extracting the things that I mentioned here. It uses aes256 with gcm chaining mode and sha348 as a hashing method for the hmac.
Coda Hale's article "How To Safely Store a Password" claims that:
bcrypt has salts built-in to prevent rainbow table attacks.
He cites this paper, which says that in OpenBSD's implementation of bcrypt:
OpenBSD generates the 128-bit bcrypt salt from an arcfour
(arc4random(3)) key stream, seeded with random data the kernel
collects from device timings.
I don't understand how this can work. In my conception of a salt:
It needs to be different for each stored password, so that a separate rainbow table would have to be generated for each
It needs to be stored somewhere so that it's repeatable: when a user tries to log in, we take their password attempt, repeat the same salt-and-hash procedure we did when we originally stored their password, and compare
When I'm using Devise (a Rails login manager) with bcrypt, there is no salt column in the database, so I'm confused. If the salt is random and not stored anywhere, how can we reliably repeat the hashing process?
In short, how can bcrypt have built-in salts?
This is bcrypt:
Generate a random salt. A "cost" factor has been pre-configured. Collect a password.
Derive an encryption key from the password using the salt and cost factor. Use it to encrypt a well-known string. Store the cost, salt, and cipher text. Because these three elements have a known length, it's easy to concatenate them and store them in a single field, yet be able to split them apart later.
When someone tries to authenticate, retrieve the stored cost and salt. Derive a key from the input password, cost and salt. Encrypt the same well-known string. If the generated cipher text matches the stored cipher text, the password is a match.
Bcrypt operates in a very similar manner to more traditional schemes based on algorithms like PBKDF2. The main difference is its use of a derived key to encrypt known plain text; other schemes (reasonably) assume the key derivation function is irreversible, and store the derived key directly.
Stored in the database, a bcrypt "hash" might look something like this:
$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
This is actually three fields, delimited by "$":
2a identifies the bcrypt algorithm version that was used.
10 is the cost factor; 210 iterations of the key derivation function are used (which is not enough, by the way. I'd recommend a cost of 12 or more.)
vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa is the salt and the cipher text, concatenated and encoded in a modified Base-64. The first 22 characters decode to a 16-byte value for the salt. The remaining characters are cipher text to be compared for authentication.
This example is taken from the documentation for Coda Hale's ruby implementation.
I believe that phrase should have been worded as follows:
bcrypt has salts built into the generated hashes to prevent rainbow table attacks.
The bcrypt utility itself does not appear to maintain a list of salts. Rather, salts are generated randomly and appended to the output of the function so that they are remembered later on (according to the Java implementation of bcrypt). Put another way, the "hash" generated by bcrypt is not just the hash. Rather, it is the hash and the salt concatenated.
This is a simple terms...
Bcrypt does not have a database it stores the salt...
The salt is added to the hash in base64 format....
The question is how does bcrypt verifies the password when it has no database...?
What bcrypt does is that it extract the salt from the password hash... Use the salt extracted to encrypt the plain password and compares the new hash with the old hash to see if they are the same...
To make things even more clearer,
Registeration/Login direction ->
The password + salt is encrypted with a key generated from the: cost, salt and the password. we call that encrypted value the cipher text. then we attach the salt to this value and encoding it using base64. attaching the cost to it and this is the produced string from bcrypt:
$2a$COST$BASE64
This value is stored eventually.
What the attacker would need to do in order to find the password ? (other direction <- )
In case the attacker got control over the DB, the attacker will decode easily the base64 value, and then he will be able to see the salt. the salt is not secret. though it is random.
Then he will need to decrypt the cipher text.
What is more important : There is no hashing in this process, rather CPU expensive encryption - decryption. thus rainbow tables are less relevant here.
Lets imagine a table that has 1 hashed password. If hacker gets access he would know the salt but he will have to calculate a big list for all the common passwords and compare after each calculation. This will take time and he would have only cracked 1 password.
Imagine a second hashed password in the same table. The salt is visible but the same above calculation needs to happen again to crack this one too because the salts are different.
If no random salts were used, it would have been much easier, why? If we use simple hashing we can just generate hashes for common passwords 1 single time (rainbow table) and just do a simple table search, or simple file search between the db table hashes and our pre-calculated hashes to find the plain passwords.
I would like to get Both CryptoJS's SHA256 and php's Crypt SHA256 output to match.
PHP crypt has a salt and a number of rounds. E.g. for 5000 rounds and salt of "usesomesillystringforsalt" it would be;
$hash = crypt('Clear Text String', '$5$rounds=5000$usesomesillystringforsalt$');
I hope im not blind, but i cant find how to reproduce this behaviour in crypto-js. Its syntax doesn't seem to allow for rounds or salt.
Is it possible or should i just resort to using the basic PHP hash instead of crypt?
The CryptoJS API doesn't provide a way to specify a salt or the number of rounds for SHA256. You could add a salt manually if necessary, and specifying rounds doesn't make sense since "plain" SHA256 always uses a fixed number of rounds (64).
The number of rounds in PHP's crypt() actually defines how often the SHA256 algorithm is applied consecutively, in order to increase the complexity of brute force attacks. The PHP source code comments on this as follows: "Repeatedly run the collected hash value through SHA256 to burn CPU cycles".
As you can see in the source code (here and here), crypt() is actually a key derivation function that only makes use of SHA256 to generate cryptographically secure, salted hashes. So it also doesn't simply append the given salt to the key, instead it's a more elaborate process.
Therefore, it is not possible to get the same results with the algorithms provided by CryptoJS.
crypt() is mainly intended for password hashing. So if you need the hashes for another purpose, hash() is a good alternative (and of course creates exactly the same results as CryptoJS.SHA256()).
However, bear in mind that any cryptography with JavaScript is generally considered harmful. Hence, you should better use SSL in your application, if possible, and generate the hashes server side. If this is an option, have a look at bcrypt.
Let's say I have am creating a webapp, where users can create a nested tree of strings (with sensitive information). These strings are presumably quite short. I want to encrypt both keys and values in this tree before saving it. All values in the tree will be encrypted client-side using a symmetric key supplied by the user. Likewise they will be decrypted client-side, when reading.
The tree is persisted in a Mongo database.
I can't decide whether I should serialize the tree and encrypt it has a whole string or whether to encrypt values individually, considering that all data in the tree will be encrypted using the same key.
What are the pros and cons of either?
From what I can tell, AES uses a block size of 128 bits, meaning that any string can grow up to 15 characters in length when encoded, which speaks in favor of encoding a serialized string (if you want to avoid overhead)
Note: Although the webapp will use both HTTPS, IP whitelisting and multifactor authentication, I want to make an effort to prevent data breach in the event the Mongo database is stolen. That's what I'm going for here. Advice or thoughts on how to accomplish this is appreciated.
Update
Furthermore, I also want my service to inspire trust. Sending data in the clear (although over HTTPS) means the user must trust me to encrypt it before persisting it. Encrypting client-side allows me to emphasize that I don't know (or need to know) what I'm saving.
I can't think of a reason why these approaches would be different in terms of security of the actual strings (assuming they are both implemented correctly). Encrypting the strings individually obviously means that the structure of the tree will not be secret, but I'm not sure if you are concerned with that or not. For example, if you encrypt each string individually, someone seeing the ciphertexts could find out how many keys there are in the tree, and he could also learn something about the length of each key and value. If you encrypt the tree as a whole serialized blob, then someone seeing the ciphertext can tell roughly how much data is in the tree but nothing about the lengths or number of individual keys/values.
In terms of overhead, the padding would be a consideration, as you mentioned. A bigger source of storage overhead is IVs: if you are using a block cipher mode such as CTR, you need to use a distinct IV for each ciphertext. This means if you are encrypting each string individually, you need to store an IV for each string. If you encrypt the whole serialized tree, then you just need to store the one IV for that one ciphertext.
Before you implement this in Javascript, though, you should make sure that you're actually getting a real improvement in security from doing client-side encryption. This article is a classic: http://www.matasano.com/articles/javascript-cryptography/ One important point is to remember that the server is providing the Javascript encryption code, so encrypting data on the client doesn't protect it from the server. If your main concern is a stolen database, you could achieve the same security by just encrypting the data on the server before inserting it in the database.
First of all, I am not a security expert ;-)
I can't decide whether I should serialize the tree and encrypt it has a whole string or whether to encrypt values individually, considering that all data in the tree will be encrypted using the same key.
I would say serializing the tree first and encrypting the result of that has the biggest con.
What plays a huge role in successfully cracking encryption is often the knowledge about certain characters that appear quite often in the original text – for example the letters e and n in English language – and doing statistical analysis based on that on the encrypted text.
Now lets say you use for example JSON to serialize your tree client-side before encrypting it. As the attacker, I would easily know that, since I can analyze your client-side script at my leisure. So I also know already that the “letters” {, }, [, ], : and " will have a high percentage of occurrence in every “text” that you encrypt … and that the first letter of every text will have been either a { or a [ (based upon whether your tree is an object or an array) – that’s already quite a bit of potentially very useful knowledge about the texts that get encrypted by your app.