【问题标题】:How to Generate ASP.NET Password using PHP如何使用 PHP 生成 ASP.NET 密码
【发布时间】:2019-01-14 04:08:22
【问题描述】:

我现有的 ap.net c# 网站正在使用 mysql 数据库。现在我计划为该网站创建移动应用程序,因为该 API 需要准备好。 我正在为 PHP Laravel 框架创建一个 API。对于RegistrationAPI需要生成密码。

Asp.net 使用其内置库生成密码,如

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

它会自动在名为“webpages_membership”的表中生成密码

注意:我正在使用与 aps.net 工作网站相同的数据库。所以我的网站将在 asp.net 中,而 api 现在将在 php 中。

我在php中找到了MembershipModel类,用于比较两个密码,但它不能生成密码。

<?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);
    }

}

我已经在 PHP 中成功创建了 Login APi,使用上面的类可以正常工作。

【问题讨论】:

  • 如果你在 .net core 中做一个 api 的身份验证部分并与 php 共享 JWT 可能会容易得多。
  • 我认为如果我能够使用 phpapi 登录,那么也应该有一些解决方案可以从 php 生成密码。 MembershipModel->verifypassword($hashedPassword, $password);也是这样做的,这里 $hashedPassword 是 .net 生成的密码,$Password 是我的纯文本密码
  • C# Web-API 或 MVC 可能是 API 的更好选择。在我看来,尝试在 PHP 中重现 C# 功能似乎是倒退了一大步。
  • 如果你在 asp.net 中做网站,你应该认真考虑使用 .Net 作为 API。

标签: c# php asp.net


【解决方案1】:

正如所有 cmets 都在建议您,如果您尝试将这项工作移植到 PHP 而不是让 PHP 通过某些 .NET 组件与后端对话,那么您可能会遇到困难.

不过,如果您打算将其移植过来,the code for WebSecurity.CreateUserAndAccount() is available on GitHub。如您所见,它依赖于当前配置的成员资格提供者对该方法的实现。

对于SimpleMembershipProviderthe implementation is very simple。这是重要的一点:

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

CreateUserRow() 不是很有趣或令人惊讶,但CreateAccount() 负责我认为你关心的部分。

您需要将两个部分移植到 PHP; Crypto.HashPassword()GenerateToken()。由于您只使用两个参数调用WebSecurity.CreateUserAndAccount(),因此您可以忽略GenerateToken() 部分(因为requireConfirmation 默认为false)。

Here's the source code for Crypto.HashPassword()。根据其评论,它执行:

带有 HMAC-SHA1 的 PBKDF2、128 位盐、256 位子密钥、1000 次迭代。
(另请参阅:SDL 加密指南 v5.1,第三部分)
格式:{ 0x00, salt, subkey }

…使用System.Security.Cryptography.Rfc2898DeriveBytes() 方法。

这将我们引向this directly related existing Stack Overflow answer,我认为可以满足您的需求。

【讨论】:

    猜你喜欢
    • 2010-12-22
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2019-05-25
    • 2014-03-27
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多