<?php
declare(strict_types=1);
$salt = 'OgybOFzbO8htTTop5nuilg==';
$goal = 'X8fKMgIbDaiNDugq1OHuiTClHruTIL/9J48thPAx2kf3VMNWhnWttE3sLH1LKQ/Yg1UUOZd0Bq6ZLtviWDP2dQ==';
$spinCount = 100000;
//$charlist = 'aejh';
$charList = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.,åäöÅÄÖ!$%#=@';
echo solve($salt, $goal, $spinCount, $charList, 3);
function solve($salt, $goal, $spinCount, $charList, $maxLength)
{
$arrayCharlist = mb_str_split($charList);
fwrite(
STDERR,
'Bruteforce 1-' . $maxLength . ' of the ' . count($arrayCharlist) . ' characters ' . $charList . PHP_EOL
);
$c = 0;
$status = static function ($c) {
fwrite(STDERR, "\r" . $c . ' @ ' . date('Y-m-d H:i:s') . PHP_EOL);
};
$status($c);
foreach (range(1, $maxLength) as $length) {
foreach (combinations('', $length, $arrayCharlist) as $combination) {
fwrite(STDERR, '.');
$c++;
if ($c % 100 === 0) {
$status($c);
}
$hash = xlsxhash($combination, $salt, $spinCount);
if ($hash === $goal) {
$status($c);
return $combination;
}
}
}
}
function combinations($prefix, $length, $charlist)
{
if ($length < 2) {
foreach ($charlist as $char) {
yield $prefix . $char;
}
return;
}
foreach ($charlist as $char) {
yield from combinations($prefix . $char, $length - 1, $charlist);
}
}
function xlsxhash($utf8Password, $base64Salt, $intSpinCount)
{
$utf16BEPassword = mb_convert_encoding($utf8Password, 'UTF-16');
$utf16LEPassword = pack('n*', ...unpack('v*', $utf16BEPassword));
$rawSalt = base64_decode($base64Salt);
$data = $rawSalt . $utf16LEPassword;
for ($i = 0; $i < $intSpinCount; $i++) {
$int32LE = pack('V', $i);
$data = hash('sha512', $data, true) . $int32LE;
}
$data = hash('sha512', $data, true);
return base64_encode($data);
}
Comments