Какие правила итерации применяются к crypt() с использованием CRYPT_EXT_DES?

Мой тестовый пример выглядит следующим образом:

echo crypt('string', '_....salt');//error
echo crypt('string', '_A...salt');//fast
echo crypt('string', '_AAAAsalt');//slow

Объяснение, как указано на http://www.php.net/manual/en/function.crypt.php:

CRYPT_EXT_DES - расширенный хэш на основе DES. "Соль" - это строка из 9 символов, состоящая из подчеркивания, за которым следуют 4 байта числа итераций и 4 байта соли. Они кодируются как печатаемые символы, 6 бит на символ, наименее значимый символ в первую очередь. Значения от 0 до 63 кодируются как "./0-9A-Za-z". Использование недопустимых символов в соли приведет к сбою crypt().

Точка - это печатный символ, так почему он возвращает ошибку? И какой "порядок" применяется к используемым символам, в результате чего "AAAA" больше итераций, чем "A..."?

4 ответа

Этот вопрос немного стар, но я нашел его, пытаясь обдумать, как создать здесь класс хеширования для внутреннего использования, и я придумал эту маленькую функцию, которая будет base64 кодировать целое число с соответствующими символами / значимостью для использоваться как 4-символьный "счетчик итераций". Возможные значения от 1 до 16 777 215

private function base64_int_encode($num){
    $alphabet_raw = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $alphabet = str_split($alphabet_raw);
    $arr = array();
    $base = sizeof($alphabet);
    while($num){
        $rem = $num % $base;
        $num = (int)($num / $base);
        $arr[]=$alphabet[$rem];
    }

    $arr = array_reverse($arr);
    $string = implode($arr);

    return str_pad($string, 4, '.', STR_PAD_LEFT);
}

Надеюсь, это поможет кому-то!

Система счисления, используемая в Extended DES:

.... - 0 (Extended DES error)
/... - 1
0... - 2
1... - 3
2... - 4
3... - 5
4... - 6
5... - 7
6... - 8
7... - 9
8... - 10

z... - 63
./.. - 64
//.. - 65
0/.. - 66
1/.. - 67

Y/.. - 100
61.. - 200
g2.. - 300
E4.. - 400
o5.. - 500
M7.. - 600
w8.. - 700
UA.. - 800
2C.. - 900
cD.. - 1000

zz.. - 4095
../. - 4096
/./. - 4097
0./. - 4098
1./. - 4099

xzzz - 16 777 213
yzzz - 16 777 214
zzzz - 16 777 215

И в связи с солью:

_/...salt - 1
_0...salt - 2
_1...salt - 3
_2...salt - 4
_3...salt - 5
_4...salt - 6
_5...salt - 7
_6...salt - 8
_7...salt - 9
_8...salt - 10

_z...salt - 63
_./..salt - 64
_//..salt - 65
_0/..salt - 66
_1/..salt - 67

_Y/..salt - 100
_61..salt - 200
_g2..salt - 300
_E4..salt - 400
_o5..salt - 500
_M7..salt - 600
_w8..salt - 700
_UA..salt - 800
_2C..salt - 900
_cD..salt - 1000

_zz..salt - 4095
_../.salt - 4096
_/./.salt - 4097
_0./.salt - 4098
_1./.salt - 4099

_xzzzsalt - 16 777 213
_yzzzsalt - 16 777 214
_zzzzsalt - 16 777 215

Код Klathmon хорош, но есть некоторые ошибки:

Первый - алфавит

It is:
./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Should be:
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Второе - порядок символов / цифр

It generates for example: ...z
But it should generate: z...

Улучшенный код:

function base64_int_encode($num) {
  $alphabet_raw='./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  $alphabet=str_split($alphabet_raw);
  $arr=array();
  $base=sizeof($alphabet);
  while($num) {
    $rem=$num % $base;
    $num=(int)($num / $base);
    $arr[]=$alphabet[$rem];
  }

  $string=implode($arr);

  return str_pad($string, 4, '.', STR_PAD_RIGHT);
}

В цитируемом параграфе сказано все: - сначала наименее значимый символ - значения от 0 до 63 кодируются как "./0-9A-Za-z"

Так что в вашем примере "_.... соль" будет означать 0 раундов, которые, очевидно, не могут работать. и "_A... соль" меньше, чем "_AAAAsalt", учитывая, что наименьший значимый символ стоит первым.

"_... Asalt" также будет больше, чем "_A... соль"

Другие вопросы по тегам