Почему crypt / blowfish генерирует одинаковый хэш с двумя разными солями?

Этот синтаксис недействителен в Oracle. Вы можете сделать это:

UPDATE table1 SET table1.value = (SELECT table2.CODE
                                  FROM table2 
                                  WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
            FROM table2 
            WHERE table1.value = table2.DESC);

Или вы могли бы быть в состоянии сделать это:

UPDATE 
(SELECT table1.value as OLD, table2.CODE as NEW
 FROM table1
 INNER JOIN table2
 ON table1.value = table2.DESC
 WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW

(Это зависит от того, рассматривается ли встроенное представление обновляется Oracle).

30
задан Dereleased 10 February 2010 в 00:30
поделиться

2 ответа

После некоторых экспериментов я пришли к выводу, что это связано со способом обращения с солью. Соль не считается буквальным текстом, а скорее строкой в ​​кодировке base64, так что 22 байта солевых данных фактически представляют собой 16-байтовую строку ( floor (22 * 24/32) == 16 ) соли. Команда "Попался!" Однако в этой реализации, как и в Unix crypt, используется «нестандартный» алфавит base64. Если быть точным, он использует этот алфавит:

./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$

65-й символ, ' $ ', является символом заполнения.

Теперь функция crypt () , похоже, способна принимать соль любой длины, меньшей или равной ее максимальной, и молча обрабатывать любые несоответствия в base64, отбрасывая любые данные, которые не соответствуют ' t составляют еще один полный байт. Функция crypt полностью выйдет из строя, если вы передадите ей символы в соли, которые не являются частью ее алфавита base64, что лишь подтверждает эту теорию ее работы.

Возьмем воображаемую соль ' 1234 '. Это полностью соответствует base64, поскольку представляет 24 бита данных, то есть 3 байта, и не несет никаких данных, которые необходимо отбросить. Это соль, у которой Len Mod 4 равно нулю. Добавьте к этой соли любой символ, и он станет солью из 5 символов, и Len Mod 4 теперь равно 1.Однако этот дополнительный символ представляет только шесть бит данных и, следовательно, не может быть преобразован в другой полный байт, поэтому он отбрасывается.

Таким образом, для любых двух солей A и B, где

   Len A Mod 4 == 0 
&& Len B Mod 4 == 1  // these two lines mean the same thing
&& Len B = Len A + 1 // but are semantically important separately
&& A == substr B, 0, Len A

Фактическая соль, используемая crypt () для вычисления хэша, фактически будет идентична. В качестве доказательства я привожу пример кода PHP, который можно использовать для демонстрации этого. Соль постоянно вращается полу неслучайным образом (на основе случайного сегмента хэша водоворота текущего времени с точностью до микросекунды), и данные, подлежащие хешированию (здесь называются $ seed ) - это просто текущее время эпохи Unix.

$salt = substr(hash('whirlpool',microtime()),rand(0,105),22);
$seed = time();
for ($i = 0, $j = strlen($salt); $i <= $j; ++$i) {
    printf('%02d = %s%s%c',
        $i,
        crypt($seed,'$2a$07$' . substr($salt, 0, $i)),
        $i%4 == 0 || $i % 4 == 1 ? ' <-' : '',
        0x0A
    );
}

И это дает результат, аналогичный следующему

00 = $2a$07$$$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
01 = $2a$07$e$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
02 = $2a$07$e8$$$$$$$$$$$$$$$$$$$.WEimjvvOvQ.lGh/V6HFkts7Rq5rpXZG
03 = $2a$07$e89$$$$$$$$$$$$$$$$$$.Ww5p352lsfQCWarRIWWGGbKa074K4/.
04 = $2a$07$e895$$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
05 = $2a$07$e8955$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
06 = $2a$07$e8955b$$$$$$$$$$$$$$$.2UumGVfyc4SgAZBs5P6IKlUYma7sxqa
07 = $2a$07$e8955be$$$$$$$$$$$$$$.gb6deOAckxHP/WIZOGPZ6/P3oUSQkPm
08 = $2a$07$e8955be6$$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
09 = $2a$07$e8955be61$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
10 = $2a$07$e8955be616$$$$$$$$$$$.hWHhdkS9Z3m7/PMKn1Ko7Qf2S7H4ttK
11 = $2a$07$e8955be6162$$$$$$$$$$.meHPOa25CYG2G8JrbC8dPQuWf9yw0Iy
12 = $2a$07$e8955be61624$$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
13 = $2a$07$e8955be616246$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
14 = $2a$07$e8955be6162468$$$$$$$.OTzcPMwrtXxx6YHKtaX0mypWvqJK5Ye
15 = $2a$07$e8955be6162468d$$$$$$.pDcOFp68WnHqU8tZJxuf2V0nqUqwc0W
16 = $2a$07$e8955be6162468de$$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
17 = $2a$07$e8955be6162468deb$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
18 = $2a$07$e8955be6162468deb0$$$.aNZIHogUlCn8H7W3naR50pzEsQgnakq
19 = $2a$07$e8955be6162468deb0d$$.ytfAwRL.czZr/K3hGPmbgJlheoZUyL2
20 = $2a$07$e8955be6162468deb0da$.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
21 = $2a$07$e8955be6162468deb0da3.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
22 = $2a$07$e8955be6162468deb0da3ucYVpET7X/5YddEeJxVqqUIxs3COrdym

Заключение? Дважды. Во-первых, он работает так, как задумано, а во-вторых, знайте, что у вас есть, или не бросайте свою соль.

35
ответ дан 28 November 2019 в 00:06
поделиться

Похоже, что выходы на самом деле разные. (da $, vs da2) для результата salt_20 и salt_21.

3
ответ дан 28 November 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: