I'm working on an SSO implementation in PHP that authenticates to a system written in C#. Here's some pseudo code to demonstrate:
$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);
This outputs: NWZiMTBhZmNhNTlmYzMxMTEzMThhZmVl
Here's the C# version from the system with which I'm integrating:
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());
This outputs: aE1k9-djZ66WbUATqdHbWyJzskMI5ABS0
I cannot figure out how to get my PHP code to do the same thing. I have a feeling it is in the salt
generation.
I've tried to translate the C# HttpServerUtility.UrlTokenDecode
function to PHP like so:
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;
}
That didn't get me to where I needed to go. Halp!
This is for Absorb LMS. Documentation of their methods are here: https://support.absorblms.com/hc/en-us/articles/222446647-Incoming-Absorb-Single-Sign-On#Methods
Thanks!