Does using a password twice when hashing it make it safer? - security

Does using a password twice when hashing it make it safer? My example is in CodeIgniter, I striped it down to just the bare minimum. Please do not point out all the things wrong with the example, it is just an example.
<?php
function user_signup(){ // The normal way
$this->load->database();
$new_user_insert = array(
'password' => sha1($salt . $this->input->post('password')));
}
function user_signup(){ // The double insert way
$this->load->database();
$new_user_insert = array(
'password' => sha1($this->input->post('password') . $salt . $this->input->post('password')));
}
}
EDIT:
My thought is that it would make the in put twice as long, an example (username: joe, password: 123456789). So instead of having a rainbow table with my hashed 123456789, it would be 123456789123456789. I know this is a over simplification, and the hash would look more like 01a967f5d27b9e910754729a669504a60d2aa865, but a would be hacker would need a bigger rainbow table.Please correct me if I am wrong.
Thank you in advance.

a would be hacker would need a bigger rainbow table
This isn't the case if the attacker knows your strategy for hashing the password.
Suppose, for simplicity's sake, that your password needs to be a 4-digit number. (Of course, this is generalizable to more complex passwords.) There are then 10,000 possible passwords. If you concatenate the password with itself to produce an 18-digit number, the attacker can deduce the second nine digits from the first nine: 1234salt1234 is potentially valid, but 1234salt4321 cannot be, and it would not be included in a rainbow table. The additional digits, bring a function of known information, add no additional complexity.
Adding a user-specific salt to the password as a hash defends against an attacker who can obtain the password hashes and who knows the system. In particular, the attacker knows the algorithm for hashing the user's password. Assuming as before a four-character numeric password, such an attacker using a brute-force strategy would still need to attempt only 10,000 combinations (0000salt0000, 0001salt0001, ..., 9999salt9999). The original strategy (not concatenating the password with itself) would also require 10,000 combinations (0000salt, ..., 9999salt), so would be no less difficult (for practical intents).

In general, no. Entering a password twice is useful to check whether a user typed it correctly, but never useful to have in your database twice.

The purpose of entering the password a second time is just to ensure that the user hasn't mistyped it! It doesn't actually improve security by itself, and certainly there would be little gain in storing in the database twice.
It is to avoid typos. If you have to type the password twice chances
are you'll make your password what you want. They want to avoid having
people whose password is "blah" having to retrieve their password
later on because they typed "blaj" by mistake. This is especially true
since password fields show as asterisks (*********) and sometimes it
is hard to tell if you typed what you thought you typed - people are
likely to make typos without even realizing it. Some websites do this
too with the email address when it is essential that is correct as
well.
why enter password 2 times?

Related

return original value of sha256 [duplicate]

This question already has answers here:
How to decrypt a SHA-256 encrypted string?
(4 answers)
Closed 1 year ago.
I have a table called user in my database and I save the passwords in sha256. And I am wondering if I can now get the original value from the sha256, to display it on the user profile frontend.
Example
use sha2::{Digest, Sha256};
fn test() {
let password = "secret value";
let password_sh256 = Sha256::digest(password.as_bytes());
let encrypted_password = format!("{:x}", password_sh256);
println!("result: {:?}", encrypted_password);
// result: "c3a57afaa51d985ac0b4117f509e2ce6dd94d520e441778736a945b4cb941755"
}
Now how could you have the original value of the variable named password making use of the variable named encrypted_password?
I appreciate any help.
SHA-256 is designed to be computationally infeasible (in simpler terms: practically impossible) to invert like you want to do. In fact, it is provably the case that there are multiple inputs that hash to the same value (although it is also currently computationally infeasible to find them) so at best, you would be able to find some input that hashed to the same value. However, as mentioned, it is very unlikely that anyone can presently do so.
Additionally, there are some things to mention. First, you should never show the user their plaintext password. You don't know if the user is in a coffee shop, library, or other public place where others might be shoulder-surfing, so you wouldn't want to expose this. In addition, you don't want to be able to invert the password for security reasons (because that means anyone else can), so there's no way to actually show it.
Furthermore, you don't want to use plain SHA-256 for password hashing. The reason is that if people pick bad passwords, like “password123,” then all the users with the bad password will have the same password hash, and it's also easy to make a giant list of passwords that are known to be compromised and look them up in the list. What you want to do is use a password hashing function like Argon2 or bcrypt that (a) uses a unique salt (random data) for each password and (b) iterates the operation multiple times so that it's slow and guessing many passwords takes a long time. Fortunately, there are libraries in Rust for doing just this, and the argon2 crate has great documentation explaining how to do just this.

Using hashcat where first 10 character of hash are known

I've web application that use MySQL
The application use password hash function from MySQL to store the password for related account
The problem is, it trim the hashed password so that it only store first 10 characters into the password field
I want to prove to my supervisor that, trimming hashed password can make different password to be entered on the login form and accepted by the application. Because those passwords has same first 10 character
To prove that, I'm planning to use hashcat. I've download quite big dictionary file to help my purpose
So, is there someone can help me how is the parameter that I should use in hashcat?
I've tried to google for the answer, but no luck
Thanks
For an answer to the actual question skip to the last section of this answer. The other sections do not answer your question directly, but you may find that this is not neccessary anymore after reading them.
Your Description Of The System
You said the system processes the password as follows
plaintext password ➜ hashed password ➜ first 10 characters of the hash
Example:
Topsecret123 ➜ *E7C95D33E14D3C2A3AE4EAB25C1D98C88593F7AC ➜ *E7C95D33E
Note that MySQL's PASSWORD() prefixes hashes with a *, so you actually only include 9 characters from the hash.
Answering The Question In The Background
You asked how to find hash collisions for the approach from above using hashcat, but what you actually wanted to know/show was
prove trimming hashed password can make different password [...] accepted by the application.
Your emphasis was on »Trimming causes multiple passwords to be accepted«. However, you overlooked that even untrimmed hashing causes multiple passwords to be accepted.
The Pigeonhole Principle
The explanation is so simple that you don't have to find a hash collision. Everyone should understand the following:
There is an infinite amount of passwords.
MySQL password hashes have a fixed length, precisely 64 bit. There can be only 264 different hashes.
The password hash function maps passwords to hashes. Since there are more passwords than hashes some passwords have to be mapped to the same hash.
If not, you would have found a compression function which would allow you to store anything in only 64 bits.
One may argue that the number of valid passwords is not infinite. But even if you would limit valid passwords to be of exactly length 11 and contain only symbols from the group [A-Za-z0-9] (has 62 symbols) there would be 6211 unique passwords:
6211 ≈ 5,2×1019 passwords
264 ≈ 1,8×1019 hashes
Therefore, there still have to be lots of collisions.
Hash Collisions
Trimming hashes is not the root cause of the collision problem, but of course it increases the likelihood of collisions enormously. Normally, hash collisions are not a problem because they happen so rarely that you don't encounter them. However, with strongly trimmed hashes like yours, collisions become a real problem.
Finding A Collision
Using Hashcat
hashcat can compute MySQL password hashes with -m 300. You can confirm this by computing SELECT Password("hashcat"); and comparing the resulting hash with the hash shown here.
However, I couldn't find a way to trim these hashes / look for prefix collisions. I guess hashcat cannot do what you want. You would have to implement a custom hashmode for hashcat. The easiest way to do this would be to alter the current implementation of hashcat's MySQL mode. I'm not sure, but maybe it is sufficient to just change const int out_len = 40; to 9. You may have to update the OpenCL versions of the same module too. Search for m00300 here.
Using A Custom Script
Alternatively, look for a list of password-hash-pairs or generate one yourself, then look for prefix collisions in that table. This was fun so I did it myself
The following python program generates trimmed hashes for some numerical passwords:
#! /usr/bin/python3
import hashlib as hl
def mySqlPwHash(password):
return hl.sha1(hl.sha1(password.encode()).digest()).hexdigest()[:9]
for number in range(0, 300000):
password = str(number)
print(password, "\t", mySqlPwHash(password))
I chose to generate 300'000 hashes because there are 169 trimmed hashes and we can expect to find a collision in √(169) = 262'144 tries (see birthday problem).
To find passwords with the same hash run the script as follows:
./collide.py | sort -k2 | uniq -Df1
In only two seconds the script finished and printed
23607 47ae310ff
251848 47ae310ff
And there you have it, two passwords (23607 and 251848) with the same trimmed hash (47ae310ff).
If your trimmed hashes actually include 10 hex-digits you can adapt the script and will find the two passwords 1874547 and 2873667 sharing the hash 47fc464b2f.

Decrypted Hash and Encrypted hash

If this password's ( qwqwqw123456 ) hash is $2a$07$sijdbfYKmgWdcGhPPn$$$.C98C0wmy6jsqA3fUKODD0OFBKJkHdn.
What is the password of this hash $2a$07$sijdbfYKmgWdcGhPPn$$$.9PTdICzon3EUNHZvOOXgTY4z.UTQTqG
And Can I know which hash algorithm is it ?
You could try to guess which algorithm was used,
depending on the format and length of the hash,
your known value etc. but there is no definitive way to know it.
And the purpose of any "hash" function is
that it is NOT reversible/decryptable/whatever.
Depending on some factors you could try to guess the original value too
(Brute force attack: Try to hash all possible values and check which hash
is equal to yours) but, depending on the count of possibilities,
the used algortihm etc. that could take millions of years. (you could also be lucky
and get the correct value within short time, but that´s unlikely).
There are other things than bruteforce-ing, but in the end,
it´s pretty much impossible to reverse a good hash function

Password salts: prepending vs. appending

I just looked at the implementation of password hashing in Django and noticed that it prepends the salt, so the hash is created like sha1(salt + password), for example.
In my opinion, salts are good for two purposes
Preventing rainbow table lookups
Alright, prepending/appending the salt doesn't really make a difference for rainbow tables.
Hardening against brute-force/dictionary attacks
This is what my question is about. If someone wants to attack a single password from a stolen password database, he needs to try a lot of passwords (e.g. dictionary words or [A-Za-z0-9] permutations).
Let's assume my password is "abcdef", the salt is "salt" and the attacker tries all [a-z]{6} passwords.
With a prepended salt, one must calculate hash("salt"), store the hash algorithm's state and then go on from that point for each permutation. That is, going through all permutations would take 26^6 copy-hash-algorithm's-state-struct operations and 26^6 hash(permutation of [a-z]{6}) operations. As copying the hash algorithm's state is freakin fast, the salt hardly adds any complexity here, no matter how long it is.
But, with an appended salt, the attacker must calculate hash(permutation of [a-z]{6} + salt) for each permutation, leading to 26^10 hash operations. So obviously, appending salts adds complexity depending on the salt length.
I don't believe this is for historical reasons because Django is rather new. So what's the sense in prepending salts?
Do neither, use a standard Key derivation function like PBKDF2. Never roll your own crypto. It's much too easy to get it wrong. PBKDF2 uses many iterations to protect against bruteforce which is a much bigger improvement than the simple ordering.
And your trick pre-calculating the internal state of the hash-function after processing the salt probably isn't that easy to pull off unless the length of the salt corresponds to the block-length of the underlying block-cypher.
If salt is prepended, attacker can make hash state database for salts (assuming salt is long enough to make a hashing step) and then run dictionary attack.
But if salt is appended, attacker can make such database for password dictionary and additionally compute only salt's hash. Given that salt is usually shorter than password (like 4 chars salt and 8 char password), it will be faster attack.
You are making a valid point, of course; but , really, if you want to increase time it takes to calculate hash, just use longer hash. SHA256 instead of SHA1, for example.

How to store and verify digits chosen at random from a PIN/Password

If I have a users 6 digit PIN (or n char string) and I wish to verify say 3 digits chosen at random from the PIN (or x chars) as part of a 'login' procedure, how would I store the PIN in a database or some encrypted/hashed version of the PIN in such a way that I could verify the users identity?
Thoughts:
Store the PIN in a reversible
(symmetrically or asymmetrically) encrypted manner, decrypt for digit checks.
Store a range of hashed permutations of the PIN against some
ID, which links to the 'random
digits' selected, eg:
ID: 123 = Hash of Digits 1, 2, 3
ID: 416 = Hash of Digits 4, 1, 6
Issues:
Key security: Assume that the key is
'protected' and that the app is not
financial nor highly critical, but
is 'high-volume'.
Creating a
wide-number number of hash
permutations is both prohibitively
high-storage (16bytes x several
permutations) and time-consuming probably overkill
Are there any other options, issues or refinements?
Yes: I know storing passwords/PINs in a reversible manner is 'contentious' and ideally shouldn't be done.
Update
Just for clarification:
1. Random digits is a scheme I am considering to avoid key-loggers.
2. It is not possible to attempt more than a limited number of retries.
3. Other elements help secure and authenticate access.
As any encryption scheme you use to store the password/pass phrase would be either prohibitively expensive, or, easily cracked I am coming down on the side of just plain storing it in plain textr and ensuring that the database and server security is up to scratch.
You could consider some lightweight encryption scheme to hide the passwords from a casual browser of the database, but, you have to admit that any scheme will have two basic vulnerabilties. One -- your program will need a password or key which will have to be stored somewhere and will be almost as vulnerable to snooping as the actual passwords sotred in plain text, and, Two -- if you have a reasonable number of users then a hacker who has access to the encrypted passwords has lots of "clue"s to aid his brute force attack, and if your site is open to the public he can insert any number of "known texts" into your database.
Since 6C3 is 20 and 10C3 is 120, I'll get a false positive (be authenticated) on 1/6th of my guesses.
This scheme is only slightly better than no authentication at all regardless of how you store the token.
I totally agree with msw but that argument is only (or mostly) valid for the six digit scheme. For the n-char approach, the false positive ratio will (sometimes...) be much lower. One improvement would be that the random characters must be entered in the same order as in the password.
Also I think that storing hashed permutations would make it relatively easy to find the key using some brute force approach. For example, testing and combining different combinations of three characters and checking those against the stored hashes. This would defeat the purpose of hashing the key in the first place so you might as well store the key encrypted instead.
Another, totally different argument, is that your users might get very confused by this odd login procedure :)
One possible solution is to use Reed-Solomon (or something like it) to construct an n-of-m scheme: generate an nth degree polynomial f(x), where n is the number of digits needed to log in, and generate the pin digits by evaluating f(x) at x=1..6. The digits combined become your full pin. Any three of these digits can then be used (along with their x coordinate) to interpolate the polynomial constants. If they are equal to your original constants, the digits are correct.
The biggest problem, of course, is to form a field out of numbers 0..9 for polynomial constant arithmetic. Ordinary arithmetic will not cut it in this instance. And my finite field is too rusty to remember if it is possible. If you go 4 bits per digit, you can use GF(2^4) to overcome this deficiency. In addition, it is not possible to select your PIN. It will need to be assigned to you. Finally, assuming you can fix all the problems, there are only 1000 distinct polynomials for a 3 of n scheme, and it is too small for proper security.
Anyhow, I don't think this will be a good method, but I wanted to add some different ideas into the mix.
You say you've other elements for authentication. If you've also passwords, you might do the following:
Ask for a password (password is stored as hash only on your side)
First check the hash of the entered password against the stored password hash
On success, continue, otherwise go back to 1
Use there entered (unhashed) password as key for symmetrically encrypted PINs
Ask for some random digits of the PIN
This way the PIN is encrypted, but the key is not stored in plain text on your side. The online portal of my bank seems to do just that (at least I hope so that the PIN is encrypted, but from the users view the login process is like the one described above).
The key is 'protected'
The app is not financial nor highly
critical,
The app is 'high-volume'.
Creating a wide-number number of hash
permutations is both prohibitively
high-storage (16bytes x several
permutations) and time-consuming
probably overkill
Random digits is a scheme I am
considering to avoid key-loggers.
It is not possible to attempt more
than a limited number of retries.
Other elements help secure and
authenticate access.
You seem to be arguing for storing the PIN in the clear. I say go for it. You're basically describing a challenge-response authentication method, and cleartext storage on the server side is common for that use-case.
Something similar to this is a one-time-pad, or a secret key matrix. The difference is that the user has to keep / have the pad with them to access. The benefit is that as long as you get the key distribution sufficiently secure, you're very safe from keyloggers.
If you want to make it so that exposure of the matrix / pad doesn't cause compromise alone, have the user use a short (3-4 number) PIN with the pad, and keep your sensitive locking mechanism.
Example of a matrix:
1 2 3 4 5 6 7 8
A ; k j l k a s g
B f q 3 n 0 8 u 0
C 1 2 8 e g u 8 -
A challenge might be: "Enter your PIN, and then the character from square B3 from your matrix."
The response might be:
98763

Resources