gpt4 book ai didi

C# SSO 哈希迁移到 PHP

转载 作者:太空宇宙 更新时间:2023-11-03 19:43:23 24 4
gpt4 key购买 nike

我正在使用 PHP 开发 SSO 实现,该实现对用 C# 编写的系统进行身份验证。这里有一些伪代码来演示:

$token = "MqsXexqpYRUNAHR_lHkPRic1g1BYhH6bFNVPagEkuaL8Mf80l_tOirhThQYIbfWYErgu4bDwl-7brVhXTWnJNQ2";
$id = "bob@company.com";
$ssokey = "7MpszrQpO95p7H";
$idAndKey = $id . $ssokey;
$salt = base64_decode(substr($token, 0, -1));
$hashed = hash_pbkdf2("sha256", $idAndKey, mb_convert_encoding($salt, 'UTF-16LE'), 1000, 24, false);
$data = base64_encode($hashed);

输出:NWZiMTBhZmNhNTlmYzMxMTEzMThhZmVl

这是我正在集成的系统的 C# 版本:

var token = "MqsXexqpYRUNAHR_lHkPRic1g1BYhH6bFNVPagEkuaL8Mf80l_tOirhThQYIbfWYErgu4bDwl-7brVhXTWnJNQ2";
var id = "bob@company.com";
var ssokey = "7MpszrQpO95p7H";
string idAndKey = id + ssokey;
var salt = HttpServerUtility.UrlTokenDecode(token);
var pbkdf2 = new Rfc2898DeriveBytes(idAndKey, salt) {IterationCount = 1000};
var key = HttpServerUtility.UrlTokenEncode(pbkdf2.GetBytes(24));
Console.WriteLine(key.ToString());

输出:aE1k9-djZ66WbUATqdHbWyJzskMI5ABS0

我不知道如何让我的 PHP 代码做同样的事情。我有一种感觉,它在 salt 一代中。

我试过将 C# HttpServerUtility.UrlTokenDecode 函数翻译成 PHP,如下所示:

function UrlTokenDecode($token) {
$numPadChars = substr($token, -1);

// add the padded count to the end
$salt = substr($token, 0, -1) . $numPadChars;

// Transform the "-" to "+", and "*" to "/"
$salt = str_replace('-', '+', str_replace('*', '/', $salt));

// base64_decode
$salt = base64_decode($salt);

return $salt;
}

这并没有让我到达我需要去的地方。住手!

这是用于 Absorb LMS。他们的方法文档在这里:https://support.absorblms.com/hc/en-us/articles/222446647-Incoming-Absorb-Single-Sign-On#Methods

谢谢!

最佳答案

我完全不懂 php,但我认为仍然可以提供帮助。首先,如我的评论所述,C# 中的 Rfc2898DeriveBytes 使用 SHA1 作为哈希函数,而不是 SHA256,这与您的文档所说的无关。

接下来,UrlTokenDecode(和Encode)是我在实践中很少见到的很奇怪的东西。它将常规 base64 转换为“url 安全”版本,如下所示:

  • 用“-”替换“+”
  • 用“_”替换“/”
  • 删除填充(末尾的'==')并附加删除填充的长度作为数字作为最后一个字符(如果没有填充 - 它仍然附加“0”)。这一步对我来说没有任何意义,但它就是这样运作的。

所以要复制你需要base64_encode,替换,删除填充,然后添加填充长度作为字符。因此,如果您的 base64 字符串以 == 结尾 - 您将其删除并在末尾添加“2”。如果没有填充 - 您添加“0”。

因此,要解码该字符串,您需要进行反向替换,然后删除最后一个字符并在该字符指示的末尾添加那么多的“=”。

所以字符串

MqsXexqpYRUNAHR_lHkPRic1g1BYhH6bFNVPagEkuaL8Mf80l_tOirhThQYIbfWYErgu4bDwl-7brVhXTWnJNQ2

在正常的 base64 中是 MqsXexqpYRUNAHR/lHkPRic1g1BYhH6bFNVPagEkuaL8Mf80l/tOirhThQYIbfWYErgu4bDwl+7brVhXTWnJNQ==

然后,我不知道你为什么要那样做

mb_convert_encoding($salt, 'UTF-16LE')

只需删除它(尽管我不了解 php - 您这样做可能有某些原因,但我无法想象是哪一个,所以要小心)。

然后作为其他答案状态 - hash_pbkdf2() 的最后一个参数应该为真。

进行此更改后,您的代码将起作用(我使用已转换为普通 base64 字符串的 token ):

$token = "MqsXexqpYRUNAHR/lHkPRic1g1BYhH6bFNVPagEkuaL8Mf80l/tOirhThQYIbfWYErgu4bDwl+7brVhXTWnJNQ==";
$id = "bob@company.com";
$ssokey = "7MpszrQpO95p7H";
$idAndKey = $id . $ssokey;
$salt = base64_decode($token);
$hashed = hash_pbkdf2("sha1", $idAndKey, $salt, 1000, 24, true);
$data = base64_encode($hashed);
echo $data;

产生预期的答案(在正常的 base64 中——你需要对其进行“url 编码”以获得精确匹配)。

关于C# SSO 哈希迁移到 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49636129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com