Using PHP to authenticate users in an ASP.NET memb

2019-05-06 22:57发布

问题:

I'm having some issues when trying to authenticate users against an existing ASP.NET membership database using PHP. I've searched the web and the existing answers that I've found don't seem to be working for me. Namely:

public static function Hash($password, $salt)
{
  $decodedSalt = base64_decode($salt);
  $utf = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
  return base64_encode(sha1($decodedSalt.$utf, true));
}

I think that part of the issue is that the password hashes aren't actually being computed with SHA-1, since the values in the database are 44 character long, base64 encoded strings (which means the inputs are probably 256 bits long). I've tried to use SHA-256 in place of SHA-1, but to no avail. I can't find a machine key in the web.config that would be salting the hashes even further, and the ASP.NET site generates the same hashes when I run locally or on the production server, so I have no idea why they aren't matching.

Web.config membership provider:

<add connectionStringName="MySqlMembershipConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" autogenerateschema="true" name="MySqlMembershipProvider" type="MySql.Web.Security.MySQLMembershipProvider, mysql.web" />

Example password that should work:

$salt = 'Mu1tp8XzfKl8dSTVAZm44A=='; // Straight from the DB
$password = 'testing';
$expectedHash = 'TQN7m8OWIyBOKVwzegWSUBVq7o7+KWFBc46J+B77mLw=' // Straight from the DB

// When using the above Hash function with SHA-256 instead of SHA-1
$generatedHash = 'rpmTmtBfWoJz71ooQGQUIIyQJKd99qhYxMUI1yda0qE='

Thoughts? Any idea why my hash doesn't match what's stored in the DB (and why/how it works when logging in through the ASP.NET site)? I've tried swapping out hash functions, reversing the password/salt concatenation, and yelling loudly while hitting my computer and none of those seemed to help.

回答1:

I took a look at the authentication question page that you linked to and one particular answer captured my attention: https://stackoverflow.com/a/4227642/633098.

Because you said that the algorithm used no longer was SHA1 but more probably SHA256 I started experimenting with HMAC hash, SHA256 instead. It didn't work at first but then I tried using both the concatenated string consisting of the password and the salt in conjunction with the salt (= key) itself, and it worked.

Here's the simple function I made:

function _hash($password, $salt) {
    return base64_encode(hash_hmac('sha256', base64_decode($salt) . iconv('UTF-8', 'UTF-16LE', $password), base64_decode($salt), true));
}

$salt = 'Mu1tp8XzfKl8dSTVAZm44A=='; // Straight from the DB
$password = 'testing';

var_dump(_hash($password, $salt));

Resulting hash: TQN7m8OWIyBOKVwzegWSUBVq7o7+KWFBc46J+B77mLw=