I am attempting to add some form security using a salted sha1 hash which I plan to use as a form security token.
I am very new to these concepts and trying to test locally.
Can I test this script locally with xampp?
Do I somehow have to have https: in xampp?
I have tried to echo the $output variable, but just get a blank page.
When I run the script I don't get any errors.

$inText = ('lightning');

function createHash($inText, $saltHash=NULL, $mode='sha1'){
// hash the text //
$textHash = hash($mode, $inText);
// set where salt will appear in hash //
$saltStart = strlen($inText);
// if no salt given create random one //
if($saltHash == NULL) {
$saltHash = hash($mode, uniqid(rand(), true));
}
// add salt into text hash at pass length position and hash it //
if($saltStart > 0 && $saltStart < strlen($saltHash)) {
$textHashStart = substr($textHash,0,$saltStart);
$textHashEnd = substr($textHash,$saltStart,strlen($saltHash));
$outHash = hash($mode, $textHashEnd.$saltHash.$textHashStart);
} elseif($saltStart > (strlen($saltHash)-1)) {
$outHash = hash($mode, $textHash.$saltHash);
} else {
$outHash = hash($mode, $saltHash.$textHash);
}
// put salt at front of hash //
$output = $saltHash.$outHash;
return $output;
}

    As far as https goes, that's separate from anything in your PHP code -- it just provides a way for the browser and web server to talk to each other in an encrypted manner. It won't have any effect on your PHP code when running it locally, whether https is used or not.

      cluelessPHP;11063091 wrote:

      Sha1 isn't secure anymore, salting is deprecated

      Try to use
      http://php.net/manual/en/function.password-hash.php

      But he's talking about a form token (presumably to safeguard against CSRF attacks), not a password. He could use password_hash() ... but is it necessary? Maybe we need an expert opinion? Do we assume that OP has read https://www.owasp.org/index.php/Cross-Site_Request_Forgery(CSRF)Prevention_Cheat_Sheet ?

      New PHP Guy wrote:

      I have tried to echo the $output variable, but just get a blank page.
      When I run the script I don't get any errors.

      It works here ... 5.2/CentOS, 5.6.5/FreeBSD .... did you actually call the function?

      echo createHash($inText);
        NogDog;11063093 wrote:

        As far as https goes, that's separate from anything in your PHP code -- it just provides a way for the browser and web server to talk to each other in an encrypted manner. It won't have any effect on your PHP code when running it locally, whether https is used or not.

        Right. In a production environment, you should run code via HTTPS, so that things like tokens and passwords will be difficult to decode if sniffed over the network. For development, it doesn't matter. So the answer to that part of the OP question is "no".

          As far as testing the "script", there needs to be more written than just a createHash function; there has to be all the other code that is supposed to use it (e.g., how this hash is going to be compared with what and when), because it will be that which the function has to work with and sets the standards for what testing is actually needed.

            Thank you all for your replies.
            I am learning here.
            That reference to OWASP will be very useful. Didn't know it existed.
            I originally asked the question because I was not getting anything from the script.
            I am using an older computer with older version of windows and xampp and wasn't sure if they were compatabile with sha1. My mistake was pointed out. I was not actually calling the function. Now that I have called the function I see it works with sha1 & sha256.

            Is salting depricated when creating tokens not passwords?

            My plan was to generate the token by using the above script and using the $inText variable like this.
            $inText = md5(uniqid(microtime(), true));
            I would then store that token in a session variable and in a hidden form input. Then compare them when the form is submitted.
            Would using the above script with sha256 and randomly generated salt be better than password_hash ? If not. Why?
            I also plan to include script to check for input names that don't match the one that are in this form.
            Validate the url.
            Filter the input values.
            And finally add google reCaptcha to the form and script.

              Well, what you've written generates a salted hash of an arbitrary string (here, "lightning"); it's pretty much what [man]password_hash[/man] does, except that function uses cryptographically strong methods.

                Yes. "lightning" in my original post. I was just using "lightning" for test purpose. In my last reply $inText = md5(uniqid(microtime(), true));.
                So would having md5 hash of microtime and random generated salt added to sha256 hash of microtime be better than password_hash?

                  Using [man]MD5[/man] won't gain you anything for a start. Note also the caution on the [man]uniqid[/man] page.

                    Weedpacket;11063119 wrote:

                    Using [man]MD5[/man] won't gain you anything for a start. Note also the caution on the [man]uniqid[/man] page.

                    If you're comfortable with the process of implementing md5(), I wonder if you could just use crypt() instead ... perhaps with Blowfish or one of the longer SHA's?

                      New_PHP_Guy wrote:

                      I am attempting to add some form security using a salted sha1 hash which I plan to use as a form security token.

                      What exactly is the purpose of this security token? If it is intended to be a token to detect CSRF, then the salt is pointless: you wouldn't even need a cryptographic hash per se, though it makes sense to use one to help avoid attacks involving the pseudorandom number generator. SHA-1 is still alright for this purpose, though you might as well use one of the algorithms in the SHA-2 family (or SHA-3, but I don't think hash() caters for it yet).

                      EDIT:
                      Oh, I see that you did imply that this was for CSRF detection.

                      New_PHP_Guy wrote:

                      Is salting depricated when creating tokens not passwords?

                      Salting is not deprecated when creating tokens: salting has always been useless when creating tokens. The basic purpose of using salts is so that identical input to a cryptographic hash function will result in differing output, which is useful for the storage of passwords. It makes no sense at all for tokens since the token would have been (pseudo)randomly generated to be used for a short period of time.

                      You don't even need to apply a cryptographic hash function to create a token: if you're using a "truly" random source to generate the token, then no matter how many unhashed tokens an attacker acquires, the attacker will not have enough information generate a token that matches the next token that your script will generate (and hence defeat the CSRF protection). But since you are probably using a pseudorandom number generator, you should use a cryptographic hash.

                      When cluelessPHP claimed that "salting is deprecated", it was probably with reference to the simple use of a salt with a cryptographic hash algorithm for password storage. Salting is of course not deprecated.

                        laserlight;11063139 wrote:

                        When cluelessPHP claimed that "salting is deprecated", it was probably with reference to the simple use of a salt with a cryptographic hash algorithm for password storage. Salting is of course not deprecated.

                        Yes although I had also recalled you'd called this script into question sometime ago, although it might have been the reasons you had listed above (I'm sure it was this code)

                        <?php
                        class Hash{
                        	public static function make($string, $salt =''){
                        		return hash('sha256', $string . $salt);
                        	}
                        
                        public static function salt($length){
                        	return mcrypt_create_iv($length);
                        }
                        
                        public static function unique(){
                        	return self::make(uniqid());
                        }
                        
                        }
                        

                          What is specifically deprecated is providing a user-supplied salt to [man]password_hash[/man]. It's perfectly capable of generating a cryptographically-random salt itself.

                            Again thanks to all for your attention in this matter.
                            All along most of you were pointing me towards password_hash() , not available until php version 5.5 . Thank you for steering me in the right direction.
                            I am using an older machine and OS so I can only run php version 5.4.31
                            Further research has led me to libraries such as random_compat-2.0.10 & password_compat-1.0.4
                            These will allow me to use random_bytes() or password_hash() which I believe will be sufficient for token generation. If I am mistaken in my belief, someone please let me know.

                            One other question. Is there any desireable gain if I seed Password_hash() with random_bytes() ?
                            Or should I just seed with a static password and rely on the random salts that password_hash generates? Check this script.

                            session_start();
                            
                             require_once "random_compat-2.0.10/lib/random.php";
                             include "password_compat-1.0.4/lib/password.php";
                            
                             function generateFormToken($form) {
                            	try {
                                $string = random_bytes(32);
                            } catch (TypeError $e) {
                                // Well, it's an integer, so this IS unexpected.
                                die("An unexpected error has occurred"); 
                            } catch (Error $e) {
                                // This is also unexpected because 32 is a reasonable integer.
                                die("An unexpected error has occurred");
                            } catch (Exception $e) {
                                // If you get this message, the CSPRNG failed hard.
                                die("Could not generate a random string. Is our OS secure?");
                            }
                            
                            $myRandomString = (bin2hex($string));
                            
                             $token = password_hash($myRandomString, PASSWORD_BCRYPT);
                             $_SESSION[$form.'_token'] = $token; 
                             return $token;
                             }
                            
                             $newToken = generateFormToken('form1'); 
                            
                            echo $newToken; /*in hidden form input*/
                            
                              New_PHP_Guy wrote:

                              All along most of you were pointing me towards password_hash() , not available until php version 5.5 . Thank you for steering me in the right direction.

                              It's a wrong direction, or rather a direction no better than hash() applied to a random token for your use case. password_hash() is great for its intended application: to hash passwords for storage. In this, it is intended to be implemented with algorithms that frustrate the cracking of passwords given that the password hashes have gotten into the wrong hands, hence users who carelessly reuse their passwords or who use poor passwords and neglect to change them after the breach are protected (though for the latter it is best practice to force users to change their passwords after the breach becomes known). In your case, you are not hashing passwords, therefore the typical extra work done by the algorithms behind password_hash is completely unnecessary, adding no security at all.

                              New_PHP_Guy wrote:

                              These will allow me to use random_bytes() or password_hash() which I believe will be sufficient for token generation. If I am mistaken in my belief, someone please let me know.

                              random_bytes() is an appropriate choice for token generation. Although it should already be cryptographically secure, you can still reasonably use it with hash() so you have a uniform-looking text-based token.

                                So, in summary.
                                Yes. Salted sha1 hash can be tested locally, if coded properly (call the function!).
                                Testing locally does not require https: , but should be used in production.
                                The best method of token generation is random_bytes().
                                If php 7 is not available, need backward compatability library to use random_bytes().
                                Finally, It is best for the developer to research each component of the code to determine it's present useability and effectiveness.
                                Sorry, I obviously did not do the proper research.
                                I do believe that posting here does tend to lead one to resources they otherwise wouldn't know exist.

                                  Write a Reply...