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 7 years ago.
Improve this question
I alway hear about how unsafe md5 hashes are, so I wrote this, in hopes that it would be more secure... I know about the other hashes, but my question is:
If I stored my passwords hashed by this function do you think that anyone could reverse or lookup these hashes in order to unobfuscate these passwords?
<?/*
Script Written By Michael O'Neal on 12/12/2015
How to use:
$info = "Info to destroy"
$salt = "Something to add to $info to spice it up"
$level = "how many repetitions of 1000 to hash $info with salt"
*/
function destroy($info, $salt, $level){
for($i=0;$i!=($level*1000)+1;$i++){
$info = md5($info.$salt);
}
return $info;
}
?>
The first question should be, why would you invent your own scheme, if there are proven ones? This looks a bit similar to PBKDF2, but it is not exactly.
Let's examine some details:
The parameter $info is not passed by reference, so without a return, your function does not do anything.
With $level = 1 how many iterations would you do, 1000, 1001?
How would you verify the password, how do you know about the used salt and the level, where are they stored?
How would you generate a safe salt, would it be binary with possible \0 characters or generated by PHPs rand() function?
All those details may look like small mistakes, but it shows how easy it is to make mistakes when it comes to password security, and a small mistake can ruin the whole security. So please consider to use the PHP function password_hash(), it handles all the difficult parts about safely storing passwords:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
Yes.
"Schneier's Law": Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break.
Now comes along Michael O'Neal who thinks he can do better.
The existing hashes have had intensive peer review by domain experts.
For hashing password the current best practice is PBKDF2 (Password Based Key Derivation Function) See NIST Special Publication 800-132 . It is well vetted.
Many implementations also provide a calibration function for the number of iterations.
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 7 years ago.
Improve this question
I write a lot of applications in C# and I'm trying to sew up some holes in my standard practices.
Specifically, I'm trying to decide on the best text to use in a message box, and I thought I'd ask the StackOverflow community since I believe that many opinions are always better than one.
What I have currently is:
"Document XXX.docx already exists. Okay to overwrite?"
Buttons for; Yes, No and Cancel
I'm really interested to see which examples turn out to be the most popular.
There are no limits on the style used; formal, casual, humourous, etc. All suggestions are welcome. Aim to err safely within political correctness though.
On a small side note: It would also be great, but by no means essential, to consider that the same text could also be suitable for a command line program.
Please note: English language only please. For other languages, please raise a new question.
Personally, I like to see a bit more context and slightly different wording. Something like:
"<existing document name>" already exists in "<destination path>".
Would you like to replace it (Y/N)?
or perhaps with even more information:
"<existing document name>" (<bytes>) (<date modified>) already exists in
"<destination path>".
Would you like to replace it with file of size <new bytes>, last modified
<new date modified> (Y/N)?
I think "replace" is a bit more clear than "overwrite" - and (speculation) may translate into other languages, and maintain the intended meaning more often.
...and one last option with new file name/location info:
"<existing document name>" (<bytes>) (<date modified>) already exists in
"<destination path>".
Would you like to replace it with file "<new file name>" in "<new path>" of
size <new bytes>, last modified <new date modified> (Y/N)?
This last one would probably just show a temp file / buffer location for an initial file save--but it is reusable, and more meaningful when doing a file copy.
Hope you find one of these useful.
Cheers,
Hans
Title: Overwrite?
"XXX.docx exists.
Would you like to overwrite XXX.docx?"
Buttons: Overwrite, Keep, Panic
Simple solutions are usually best, for example windows user might find it familiar to see a message :
He has 3 options :
Replace
Abort action x3
Create with a new name
Hi I'm trying to generate a similar sha256 hex, but I can't seem to get a matching one. I want to generate just about any password using a random key.
In this case, I'm using test123 : ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae
Here is my code:
print "Final Hash: " . generateHash("ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae", "fx4;)#?%") . chr(10);
sub generateHash {
my ($strPass, $strLoginKey) = #_;
my $strHash = encryptPass(uc($strPass), $strLoginKey);
return $strHash;
}
sub encryptPass {
my ($strPassword, $strKey) = #_;
my $strSalt = 'Y(02.>\'H}t":E1';
my $strSwapped = swapSHA($strPassword);
print "First Swap: " . $strSwapped . chr(10);
my $strHash = sha256_hex($strSwapped . $strKey . $strSalt);
print "Hashed Into: " . $strHash . chr(10);
my $strSwappedHash = swapSHA($strHash) . chr(10);
print "Last Swapped: " . $strSwappedHash . chr(10);
return $strSwappedHash;
}
sub swapSHA {
my ($strHash) = #_;
my $strSwapped = substr($strHash, 32, 32);
$strSwapped .= substr($strHash, 0, 32);
return $strSwapped;
}
Any help would be greatly appreciated!
The output I get:
Original Hash: ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae
Hashed Into: 34b6bdd73b3943d7baebf7d0ff54934849a38ee09c387435727e2b88566b4b85
Last Swapped: 49a38ee09c387435727e2b88566b4b8534b6bdd73b3943d7baebf7d0ff549348
Final Hash: 34b6bdd73b3943d7baebf7d0ff54934849a38ee09c387435727e2b88566b4b85
I am trying to make the output have final value same as input
Final Hash: ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae
and I want to do this by reversing the "Hashed Into" value.
SHA, as a hashing algorithm, is designed to prevent collisions. i.e. part of its power, and usefulness, is in limiting the strings which will hash to the same resultant value.
It sounds like you want to find a second string which will hash to the same hashed value as test123 hashes to. This kind of goes the intent of using SHA in the first place.
It is possible to brute force the values with SHA, i.e. given a hashed value, you can brute force the value that was hashed by computing hashes and comparing the hashed value to the target value. This will take some time. Other algorithms, such as bcrypt, are more difficult to brute force, but are more computationally expensive for you also.
Here is another post related to brute forcing SHA-512, which is effectively equivalent in algorithm to SHA-256. The linked post is Java as opposed to Perl, but the concepts are language agnostic. How long to brute force a salted SHA-512 hash? (salt provided)
You're badly misunderstanding what a hash is for. It's a ONE WAY street by design. It's also designed to have a very low probability of 'collision' - two source values that hash to the same result. And by 'very low' I mean 'for practical purposes, it doesn't'. A constrained string - such as a password - simply won't do it.
So what typically happens for passwords - my client takes my password, generates a hash, sends it to the server.
The server compares that against it's list - if the hash matches, we assume that my password was correct. This means at no point is my password sent 'in the clear' nor is possible to work out what it was by grabbing the hash.
To avoid duplicates showing up (e.g. two people with the same password) usually you'll hash some unique values. Simplistically - username + password, when hashed.
The purpose of authenticating against hashes, is to ensure the cleartext password is never required to be held anywhere - and that is all. You still need to secure you communication channel (to avoid replay attacks) and you still need to protect against brute force guessing of password.
But brute forcing hashes is by design an expensive thing to attempt. You will see places where 'rainbow tables' exist, where people have taken every valid password string, and hashed it, so they can rapidly crack retrieved hashes from the server. These are big, and took a long time to generate initially though, and are defeated at least partially by salting or embedding usernames into the hash.
But I cannot re-iterate strongly enough - don't ever hand roll your own security unless you're REALLY sure what's going on. You'll build in weaknesses that you didn't even know existed, and your only 'security' is that no one's bothered to look yet.
You should not do this. It is insecure and vulnerable to dictionary attacks.
The correct way to turn passwords into things you store, is to use a PBKDF like "bcrypt" (password-based-key-derivation-function).
Check out Digest::Bcrypt
Word of caution: if anyone ever tells you (or helps you) to use a "hash" for storing passwords, they do not know anything about security or cryptography. Smile at them, and ignore everything they say next.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Its been discussed here before, but there seems to be no conclusion.
Ideally, don't want to maintain state (upgraded/not upgraded) in the database etc. so, here is what I'm thinking:
bcrypt the MD5'd password, and use "username + something else" as a salt.
Does this scheme make any sense?
Also, in general is it a good idea to use the username as a part of the salt? I read somewhere that adding a different salt to each hash makes it more secure. Is that correct (especially in context of bcrypt)?
Surely it is a good idea to switch to a more secure hash algorithm. There is a function password_hash() you can use for creating a BCrypt hash:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
From your answer i guess that you used an unsalted MD5 value, so double hashing can be a good solution here. Just pass the MD5 hash to the password_hash() function, it will generate a safe salt on its own.
// Migrating the old MD5 hashes to MD5-BCrypt
$hashToStoreInDb = password_hash($existingMd5Hash, PASSWORD_DEFAULT);
For verification first check for a double hash, and then verify the password accordingly.
if (checkIfDoubleHash($existingHashFromDb))
{
$isPasswordCorrect = password_verify(MD5($password), $existingHashFromDb);
// Update database with pure BCrypt hash
if ($isPasswordCorrect)
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
}
else
{
$isPasswordCorrect = password_verify($password, $existingHashFromDb)
}
The stored hashes can be recognized by the leading $ or by a separate db field, a BCrypt hash for example always starts with a $ character, an MD5 hash does not.
A salt should not be derrived from other parameters and it should be unique per password. The password_hash() function will take care of this. Since a rainbowtable must be built fore each salt, an attacker would have to build a rainbowtable for each password. For more information you can have a look at my tutorial about secure password storing.
I have a question regarding password hashing. I found a great tutorial on http://crackstation.net/hashing-security.htm. This is how I create a hash from the password using this code:
$hashed_password = create_hash(form_password);
The problem with this code is that it creates a different hash for the same password every time. I guess it's because of adding a random salt to the password:
function create_hash($password)
{
// format: algorithm:iterations:salt:hash
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" .
base64_encode(pbkdf2(
PBKDF2_HASH_ALGORITHM,
$password,
$salt,
PBKDF2_ITERATIONS,
PBKDF2_HASH_BYTES,
true
));
}
So due to this, I cannot compare the hash created from the password typed by the user at the login with the hash retrieved from the database, because that hash will never be the same with the one stored in the database. The only way I see that it can be done is to store the salt in another column, or am I wrong?
A thing also annoys me. The format of the hast is e.g. sha256:1000:u9p+OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wficCU0EG. A hacker obviously knows this form of hash so the algorythm that created this hash is clear for him. Let's suppose the database has been compromised and thousands of these hash codes were revealed. Doesn't having this form of hash code raise security issues? I guess a simple OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wfic would be better because it reveals nothing about the encryption mechanism.
Read this link to Wikipedia here
It explains more about the use of a random salt. The key information there is that the random salt is stored in the same database as the hashed password. It is only created randomly a few time, when the user creates or changes their password. It is used whenever authentication is required.
Leaving the info about which algorithm it used to create the password hash leaves you the option of changing the algorithm at some time in the future without interrupting your users. If you decide up upgrade the hash algorithm you wait until a user logs in. At that point you have their password in plain text. Once you authenticate against the old algorithm, you rehash and store the new hash in their database row. It may take months or years for all users to log in but once they have they will accrue the benefits of better hashing. So you would then send out an email asking them to login and read your special news about better security (and as a side effect, improve their hashed password).
Here is an interesting discussion of password hashing StackOverflow:Passwords Storage Hash ...
The reason two hashes of the same password don't match for you is because the result of create_hash() includes the salt, which is randomly generated.
To get the same hash, you have to provide the salt as you validate. The code CrackStation.net provides makes this super simple - just store the result of create_hash() in your database, exactly as-is. To confirm a user entered the correct password, use
validate_password('provided-password','hash-from-database');
This will return a boolean of whether the password was correct. Using this method is better than writing your own, because it is specifically designed to prevent certain hints at what the correct password might be based on the time it takes to return an answer. This is a minor weakness, but better to avoid it anyway, especially since the provided function takes care of it for you.
The provided functions give you a solid implementation, so don't mess with it too much. The hash includes those extra details - sha256:1000 - in order to allow future changes to your hashing without affecting the ability of existing users to login; it will simply use the method provided in the hash, no matter what the current method is.
As far as showing a potential attacker how the hash was created: the format does show everything about how, but this doesn't matter very much at all. An attacker can easily figure out the method used from one or two known password:hash pairs. Far more important than this is using a good algorithm. The goal is to make it difficult to impossible to crack the password even with all the details, as security by obscurity is poor security.
Finally, just to reiterate, you do not need to store the salt in a separate column, just leave the big 70-80 character chunk it returns alone as your hash and let the functions take care of everything for you - anything else is a waste of time and resources
To add a bit more to the excellent accepted answer:
The point about salting the hash is to make it impossible for someone to come along with a huge pile of pre-encrypted hashes and try them one by one. Even with the salt in your database, they'd have to hash every possible dictionary entry against that salt to successfully match a hash. And the salt needs to be different every time to prevent duplicate entries (they hack one password, they have that same password that other users have entered).
As for not being able to compare the login hash to the stored hash, that is on purpose: you use a validation function to check the login password against the stored password, not a string comparison function.
Store the salt then add the salt to the password then turn it into a hash then store it.
Then to compare the passwords you retrieve the salt and add it to he password, convert it into a hash and then compare the two hashes.
(python example, the indentation is messed up when I copied the code from my code)
def Createpassword():
import random
import hashlib
username = input("type your username")
newpassword = input("type your new password? ")
#adds some salt
b = random.randint(1, 2000000000000)
randomsalt = str(b)
saltedpassword = (newpassword + randomsalt)
#hashes the newpassword
saltedpassword = saltedpassword.encode('utf-8')
h = hashlib.sha256(saltedpassword)
finsh = h.hexdigest()
#creates file names
saltname = username + "salt.txt"
username = username + ".txt"
#saves the hashedpassword and the salt
text_file = open(username, "w")
text_file.write(finsh)
text_file.close()
text_file = open(saltname, "w")
text_file.write(randomsalt)
text_file.close()
print("your new password has been saved")
def EnterPassword():
trys = 0
while (trys < 3):
username = input("type your username: ")
#takes password input
password = input("type your password: ")
#gets file names
saltname = username + "salt.txt"
username = username + ".txt"
#opens salt file
text_file = open(saltname, "r")
salt1 = text_file.read(50)
text_file.close()
#opens the hashed passwords file
text_file = open(username, "r")
correctpassword = text_file.read(500)
text_file.close()
#adds the salt to the password input
saltedpassword = password + salt1
#hashes the saltedpassword
saltedpassword = saltedpassword.encode('utf-8')
m = hashlib.sha256(saltedpassword)
hashedpassword = m.hexdigest()
#compears hashed passwords
if hashedpassword != correctpassword:
trys += 1
print("your password or username is incorrect")
if trys == 3:
print("you have been locked out for using to many failed trys")
if hashedpassword == correctpassword:
print ("Password Correct ")
#done give access
trys = 0
break
(I'm new to programming so feel free to correct me)
I have some strings and some hashes of them, but I don't know which hash function is used. Any idea?
String hash
NN34W f8b46bcdc3b3c92
EM3M3 d8015ca876fd051
HXDKD a740e97464e5dfe
AKREJ aa7aa2dadfcbe53
3bNMK 0f11440639191d9
Edit:
Thank for answers, it's a hash of the captcha.
https://registracia.azet.sk/
If you check URL of captcha image, on the end is HASH value. This
On the server are send in HTTP POST are send TEXT: (P92M4) and HASH (72fec89a2e0ade2) and other values.
I like know how comptute hash of the TEXT P92M4, and control with HASH value, which is send on server.
Because I like make own captcha system for my school project, so I first analyzing situation and weakness.
As I understand your situation, a POST request sends both the "text" and the "hash" to the CAPTCHA server. This then uses whatever hash function they use to hash your text, checks to see if it matches the hash, and decides whether or not you succeeded. Presumably, the server sends you the image, as well as the hash, and then you enter the text.
As such, if you figured out the hashing function, you'd have completely broken this CAPTCHA system: All you would need to do is hash any string using their hashing function, and then when sending your POST request, ignore the hash they sent you and merely send them your computed text and hash pair. Thus, you could very easily automate successfully passing the CAPTCHA challenge.
To illustrate how difficult "reversing" the hash might be, consider the following hash that they very well might use:
Split the TEXT up alternating letters: thus ABCDE becomes ACE and BD
md5 the two halves using salts "fj49w0utw4a" and "r8h3wlsd"
md5("fj49w0utw4a"."ACE") is 115c05f0e5300f958ba01caa64b989f
md5("r8h3wlsd"."BD") is 74eecae86ef46382eb95443a1b1fa8f5
Take every 3rd char of the first string and every 4th char of the second, and alternate them until you have 15 chars
115c05f0e5300f958ba01caa64b989f becomes 55e09b1ab9
74eecae86ef46382eb95443a1b1fa8f5 becomes e8425af5
Final hash value for "ABCDE": 5e58e40295ba1fa
There is really no way you are ever going to reverse engineer that.
UPDATE
Note that CAPTCHAs as described above (and implemented on that site) are extremely insecure, as they only require one valid text/hash combination to be known
To demonstrate, use Firebug or equivalent and navigate to the CAPTCHA area of the form. We will be editing some hidden values.
Change the form[captcha_url] value from https://pokec.azet.sk/sluzby/system/captcha/[somehash] to https://pokec.azet.sk/sluzby/system/captcha/ee2be1f239e5d17
Change the form[captcha_hash] value from [somehash] to ee2be1f239e5d17
Regardless of what the picture says, type "P22KD" for the CAPTCHA
There are several ways to mitigate this vulnerability. As Tangrs suggested, you can store the hash value in a session variable so that it cannot be manipulated by the client. Less elegant but also effective is to store the submitted CAPTCHA in a database and not allow duplicate CAPTCHAs, as is implemented on the link in the question. This is fine, until you start running out of unused CAPTCHAs and end up getting collisions.
Seems smaller than any industry hash... possibly it's propriety?
A bit more info would help though, what language, where did you get it from?