0

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.

user2524169
  • 267
  • 1
  • 2
  • 12
  • 1
    Could you clarify what you are trying to generate a similar hash to? I would be concerned that your intent here violates the intent of using an algorithm like Sha - but hard to understand what you really want here. – Mike Curry Feb 22 '15 at 07:36
  • I want the generated hash to match the first one which as I mentioned `test123`. This is for a project of mine, it is to prevent brute forcing. – user2524169 Feb 22 '15 at 07:37
  • I am not sure if I understand. Just to clarify, you expect the output of `generateHash( "ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae", "fx4;)@?%" )` to be `"test123"`? – Neil Slater Feb 22 '15 at 07:38
  • No I expect it to be `ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae` – user2524169 Feb 22 '15 at 07:44
  • 2
    You could of course just return the first param. Which part of the manipulation in the `encryptPass` function do you think is reversing which hash? You may have a misunderstanding that secure hashes encrypt/decrypt data - they do not. The hash is one-way function, it is not possible to go backwards, other than by brute-force guessing. – Neil Slater Feb 22 '15 at 07:45

3 Answers3

1

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)

Community
  • 1
  • 1
Mike Curry
  • 1,609
  • 1
  • 9
  • 12
  • In fact the OP has created a simple cryptographic PRNG. – Neil Slater Feb 22 '15 at 07:44
  • Well that is true but if I dont get this fixed, I won't be able to login to my server, I would keep getting an incorrect password error. I don't want to go more into detail about that however. – user2524169 Feb 22 '15 at 07:46
  • 2
    @user2524169: Your misunderstanding about use and behaviour of secure hashes is going to make your login code insecure - the opposite of your intent. Look for something pre-packaged instead, such as `Authen::Passphrase` (use it with bcrypt algorithm, and you will have some good defense against brute forcing) – Neil Slater Feb 22 '15 at 07:50
  • 1
    Hashing is a "one way" process. They are not designed to be able to reverse engineer the original value that was hashed. And the easier this is to do, i.e. the easier it is to create a string that hashes to a particular hashed value, the worse the hashing algorithm. – Mike Curry Feb 22 '15 at 07:50
  • @Neil Slater aah ok, will edit - still confused by the question. – Mike Curry Feb 22 '15 at 08:04
  • The point of this is actually a tcp client/server. The client sends an encrypted hash, the server generates a similar hash by reverse engineering and check if both match. Now I could just fetch the already encrypted password from the database and authenticate the client but I don't want to because I don't want the client bruteforcing my server and if that's going to happen then my server is going to be messed with, thus if the clients hash doesn't match with the generated hash, then the client is removed from the server. – user2524169 Feb 22 '15 at 08:14
  • 1
    This is why people implement lock outs or time delays on multiple unsuccessful authentication attempts to avoid brute force. The correct, and standard way to compare passwords, is to compare the hashed value of the submitted password, with the hashed version on the database. Reverse engineering the hashed value is not really a good way to do it. – Mike Curry Feb 22 '15 at 08:16
  • 2
    Also, the client would not generally send a hashed version of the password, they would send the plaintext (over an encrypted communication protocol), and the server side would hash it - this allows the server to also apply an appropriate salting strategy. Sending a hashed or encrypted version is possible - but there are considerations. – Mike Curry Feb 22 '15 at 08:18
  • 1
    @user2524169: Are you writing code to *authenticate* the client for a series of requests, or writing session validation code that is supposed to run on *each* request from the client? – Neil Slater Feb 22 '15 at 08:27
  • @Neil Slater I'm authenticating multiple clients with different passwords, so I want each encryption generated by the client to match the encryption generated by the server. Please help me fix the script, I've done the same thing with md5 before using the same method and it worked. I also updated the script a bit, I made a small mistake. – user2524169 Feb 22 '15 at 11:34
  • 2
    @user2524169: Please show how your MD5 code worked, that would help clarify what you need. I doubt it was the same at all. Also please update your example output, it *still* does not match your code, making it very difficult to understand you. Your existing script is not fixable for any purpose that I can see. – Neil Slater Feb 22 '15 at 12:18
1

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.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
0

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.

cnd
  • 1,689
  • 16
  • 14
  • Given that the bcrypt algorithm is based on a hashing algorithm, I am not sure about your "word of caution"? Either way, although this is good advice for storing authentication data, it is not too clear whether it addresses the OP's question, and may have been better as a comment instead. – Neil Slater Feb 23 '15 at 16:47