return original value of sha256 [duplicate] - rust

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.

Related

Rust: How to hash a string?

I'm trying to create a console application in Rust where you have to enter a password to access the rest of the file, so I wanted to ensure that you can't just read the file to find the password, so I wanted to store the password as a hash, so its (improbably) irreversable.
I looked up hashing in Rust, but they seem to be only usable with structs, while I'm trying to insert a String. Is a struct the only way to be able to do this?
The built-in Hash class in Rust is designed to process data for the purpose of entry into a HashMap or HashSet. This isn't suitable for password verification.
If you want to perform password verification, you should use a password hash like Argon2id or scrypt. You can find these in the argon2 and scrypt crates. Password hashes always take bytes, so you will want to access your String as a &[u8]. The password_hash crate provides traits you can use to turn these into a serialized password.
If your goal is to encrypt the remainder of the file with the password, then you should use one of the bindings to NaCl. This library has primitives that are designed to be secure. You would use the password hash functionality with a random salt to generate a key, and then use that as the key input to a secret box with a random nonce. There are other ways to do this, but unless you are well versed in cryptography, using NaCl is a smart choice since it is harder to misuse.

Keying Hashes/Login Security?

I am going to use hashing function, with salt:
$stored_pass = md5(md5($salt).md5($plain_pass)); **
/// I am wanting to know an efficient way to key/authenticate that hash.
I read up a bit about keying hashes, and MAC's, but didn't quite grasp HMAC's; so just figured that wrapping the hash in an encryption function, like aes, would work. ///
EG
$stored_pass = aes(md5(md5($salt).md5($plain_pass))); **
I would like to know the following:
Why key hashes for login? (Examples would be nice)
Methods for keying hashes? (Specifically for use in loign)
Disadvantages?
Are there still ways our hashing/password validation system could be more secure? (After we factor in hash, salted, keyed)
** What is the most "secure hashing algorithm?
" Secure by hardest to crack.
/// I read that sha-512 was one of the most secure; but then read contradicting articles stating, sha in any form should not be used, and something like bcrypt/scrypt should be used or PBKDF2. Then I read that bcrypt shouldn't be used, and has limitations. So I'm a bit confused. ///
When providing hash algorithms, I'd like to know the following:
What are the limitations of the hash algorithm?
Upsides?
Downsides?
/// My main concern is user security, so if that means less 'speed' I'm not bothered. In my eyes the login function's purpose is user security, so reducing the credibility of that security for a few milliseconds seems silly to me. (Just personal opinion). ///
Also I'd appreciate comments on my function:
$stored_pass = aes(md5(md5($salt).md5($plain_pass))); **
And any alternatives would be appreciated.
Note: I know some suggest using some sort of api for this, with functions already written, but that's not really what I'm looking for. I'd prefer to learn more about it myself.
I am going to use hashing function, with salt:
$stored_pass = md5(md5($salt).md5($plain_pass));
Don't use MD5. Learn how to safely store passwords instead. That page might very well answer all of your questions.
/// I am wanting to know an efficient way to key/authenticate that hash.
I read up a bit about keying hashes, and MAC's, but didn't quite grasp HMAC's; so just figured that wrapping the hash in an encryption function, like aes, would work. ///
MACs aren't the proper tool for the job here either, even if it seems tempting to use them. Maybe this primer on cryptography concepts will help illuminate the difference, but basically:
MAC - Provide tamper-resistance for a message.
Password hash - Slow, salted hashing algorithm.
They're totally different use-cases. (Although, PBKDF2 uses a MAC algorithm internally, so I can understand if you were confused by that.)
Encrypting a hash isn't what a MAC does, either. HMAC in particular is basically:
Hash your message (with a minor transformation).
Hash the key and output of step 1 (with another minor transformation).
/// I read that sha-512 was one of the most secure; but then read contradicting articles stating, sha in any form should not be used, and something like bcrypt/scrypt should be used or PBKDF2. Then I read that bcrypt shouldn't be used, and has limitations. So I'm a bit confused. ///
Easy answer:
Use password_hash() to create password hashes.
Use password_verify() to authenticate passwords against hashes.
Stop worrying about it.
The limitations of bcrypt (truncating after 72 characters OR the first NUL byte -- which are mentioned in the first article I linked to) aren't a practical concern, and rolling your own crypto is definitely less secure than using bcrypt.
If you are absolutely concerned about the bcrypt limitations, do this:
function bcrypt_sha384_hash($password, $cost = 10)
{
$fasthash = base64_encode(
hash('sha384', $password, true)
);
return password_hash($fasthash, PASSWORD_BCRYPT, ['cost' => $cost]);
}
function bcrypt_sha384_verify($password, $storedHash)
{
$fasthash = base64_encode(
hash('sha384', $password, true)
);
return password_verify($fasthash, $storedHash);
}

how to get original value from hash value in node.js

I have created hash of some fields and storing in database using 'crypto' npm.
var crypto = require('crypto');
var hashFirtName = crypto.createHash('md5').update(orgFirtName).digest("hex"),
QUESTION: How can I get the original value from the hash value when needed?
The basic definition of a "hash" is that it's one-way. You cannot get the originating value from the hash. Mostly because a single value will always produce the same hash, but a hash isn't always related to a single value, since most hash functions return a string of finite/fixed length.
Additional Information
I wanted to provide some additional information, as I felt I may have left this too short.
As #xShirase pointed out in his answer, you can use a table to reverse a Hash. These are known as Rainbow Tables. You can generate them or download them from the internet, usually from nefarious sources [ahem].
To expand on my other statement about a hash value possibly relating to multiple original values, lets take a look at MD5.
MD5 is a 128-bit hash. This means it can hold 2^128 bits, or (unsigned) 0 through 340,282,366,920,938,463,463,374,607,431,768,211,455. That's a REALLY big number. So, for any given input you have a 1 in 340,282,366,920,938,463,463,374,607,431,768,211,456 chance that it will collide with the same hash result of another input value.
Now, for simple data like passwords, the chances are astronomical. And for those purposes, who cares? Most of the time you are simply taking an input, hashing it, then comparing the hashes. For reasons I will not get into, when using hashes for passwords you should ALWAYS store the data already hashed. You don't want to leave plain-text passwords just lying about. Keep in mind that a hash is NOT the same as encryption.
Hashes can also be used for other reasons. For instance, they can be used to create a fast-lookup data structure known as a Hash Table. A Hash Table uses a hash as sort of a "primary key", allowing it to search a huge set of data in relatively few number of instructions, approaching O(1) (On-order of 1). Depending on the implementation of the Hash Table and the hashing algorithm, you have to deal with collisions, usually by means of a sorted list. This is why the Hash Table isn't "exactly" O(1), but close. If your hash algorithm is bad, the performance of your Hash Table can begin to approach O(n).
Another use for a hash it to tell if a file's contents have been altered, or match an original. You will see many OSS project provide binary downloads that also have an MD5 and/or SHA-2 hash values. This is so you can download the files, do a hash locally, and compare the results against theirs to make sure the file you are getting is the file they posted. Again, since the odds of two files matching another is 1 in 340,282,366,920,938,463,463,374,607,431,768,211,456, the odds of a hacker successfully generating a file of the same size with a bad payload that hashes to the exact same MD5/SHA-2 hash is pretty low.
Hope this discussion can help either you or someone in the future.
If you could get the original value from the hash, it wouldn't be that secure.
If you need to compare a value to what you have previously stored as a hash, you can create a hash for this value and compare the hashes.
In practice there is only one way to 'decrypt' a hash. It involves using a massive database of decrypted hashes, and compare them to yours. An example here

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

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

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?

Resources