Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Generate ASP.NET Password using PHP

Tags:

c#

php

asp.net

I have existing ap.net c# website is working with mysql database. now i am planning to create mobile app for that website for that API needs to be ready. I am creating an API into PHP Laravel Framework. for RegistrationAPI needs to generate password.

Asp.net using its inbuilt library for generating password like

WebSecurity.CreateUserAndAccount("username", "password");

it automatically generates password in table called "webpages_membership"

Note: I am using same database which is used by aps.net working website. so my website will be in asp.net and api will be now in php.

I found MembershipModel class in php which is used to compare two password but it can not generate password.

<?php

/*
 * Author  : Mr. Juned Ansari
 * Date    : 15/02/2017 
 * Purpose : It Handles Login Encryption And Decryption Related Activities
 */

class MembershipModel {

    function bytearraysequal($source, $target) {
        if ($source == null || $target == null || (strlen($source) != strlen($target)))
            return false;
        for ($ctr = 0; $ctr < strlen($target); $ctr++) {
            if ($target[$ctr] != $source[$ctr])
                return false;
        }
        return true;
    }
    //This Function is Used to verifypassword
    function verifypassword($hashedPassword, $password) {

        $PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
        $PBKDF2SubkeyLength = 32; // 256 bits       
        $SaltSize = 16; // 128 bits


        if ($hashedPassword == null) {
            return false;
            //show_error("hashedPassword is null");
        }
        if ($password == null) {
            return false;
            //show_error("Password is null");
        }

        $hashedPasswordBytes = base64_decode($hashedPassword);

        if (strlen($hashedPasswordBytes) != 48) {
            return false;
        }

        $salt = substr($hashedPasswordBytes, 0, $SaltSize);

        $storedSubkey = substr($hashedPasswordBytes, $SaltSize, $PBKDF2SubkeyLength);

        $generatedSubkey = $this->encript('sha1', $password, $salt, $PBKDF2IterCount, $PBKDF2SubkeyLength, true);

        return $this->bytearraysequal($storedSubkey, $generatedSubkey);
    }

    function encript($algorithm, $password, $salt, $count, $key_length, $raw_output = false) {
        $algorithm = strtolower($algorithm);
        if (!in_array($algorithm, hash_algos(), true))
            return false;
        //show_error('PBKDF2 ERROR: Invalid hash algorithm.');
        if ($count <= 0 || $key_length <= 0)
            return false;
        //show_error('PBKDF2 ERROR: Invalid parameters.');

        $hash_length = strlen(hash($algorithm, "", true));
        $block_count = ceil($key_length / $hash_length);

        $output = "";
        for ($i = 1; $i <= $block_count; $i++) {

            $last = $salt . pack("N", $i);

            $last = $xorsum = hash_hmac($algorithm, $last, $password, true);

            for ($j = 1; $j < $count; $j++) {
                $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
            }
            $output .= $xorsum;
        }
        return substr($output, 0, $key_length);
    }

}

I have successfully created Login APi in PHP which is working fine using above class.

like image 575
Juned Ansari Avatar asked Aug 07 '18 06:08

Juned Ansari


1 Answers

As all the comments are advising you, you’re probably doing it the hard way if you try to port this work over to PHP instead of letting PHP talk to the backend via some .NET component.

Nevertheless, if you’re set on porting it over, the code for WebSecurity.CreateUserAndAccount() is available on GitHub. As you can see, it leans on the currently-configured membership provider's implementation of that method.

For SimpleMembershipProvider, the implementation is very simple. Here’s the important bit:

CreateUserRow(db, userName, values);
return CreateAccount(userName, password, requireConfirmation);

CreateUserRow() isn't very interesting or surprising, but CreateAccount() is responsible for the part I think you care about.

There are two parts that you'd need to port to PHP; Crypto.HashPassword() and GenerateToken(). Since you're calling WebSecurity.CreateUserAndAccount() with only two parameters, you can ignore the GenerateToken() part (since requireConfirmation defaults to false).

Here's the source code for Crypto.HashPassword(). As per its comment, it performs:

PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.
(See also: SDL crypto guidelines v5.1, Part III)
Format: { 0x00, salt, subkey }

…using the System.Security.Cryptography.Rfc2898DeriveBytes() method.

Which leads us to this directly related existing Stack Overflow answer, which I think gives you what you want.

like image 162
Kit Grose Avatar answered Nov 08 '22 06:11

Kit Grose