Членство SHA1 хэш не одинаков для всех пользователей
У меня есть пользовательская таблица, которая была в виде простого текста и перенесена в поставщика членства.
Используя ColdFusion (текущая система), мне удалось зашифровать пароль одного пользователя (тестовый пользователь), и он идеально подошел. Но теперь последующие пользователи не совпадают. Что я делаю неправильно.
<cfscript>
theEncoding = "UTF-16LE";
thePassword = "dtD3v310p3r!";
base64Salt = "JZjdzUXREM0A7DPI3FV3iQ==";
theSalt = charsetEncode( binaryDecode(base64Salt, "base64"), theEncoding );
theHash = hash(theSalt & thePassword, "SHA1", theEncoding);
// hash always returns hex. convert it to base64 so it matches DNN
theBase64Hash = binaryEncode(binaryDecode(theHash, "hex"), "base64");
WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>");
WriteOutput("DBPassword= 5khDDMmoFtW+j99r/whE/TjyIUo= <br />");
theEncoding = "UTF-16LE";
thePassword = "DT!@12";
base64Salt = "+muo6gAmjvvyy5doTdjyaA==";
theSalt = charsetEncode( binaryDecode(base64Salt, "base64"), theEncoding );
theHash = hash(theSalt & thePassword, "SHA1", theEncoding);
// hash always returns hex. convert it to base64 so it matches DNN
theBase64Hash = binaryEncode(binaryDecode(theHash, "hex"), "base64");
WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>");
WriteOutput("DBPassword= nfcqQBgeAm0Dp1oGZI0O70Y6DvA= <br />");
</cfscript>
Первый работает на 100%. Но второй нет. Второй производит значение Hash 86SrPKXW5xywDYoC8MVy0q259sQ=
1 ответ
Хм.. Я думаю, что-то может пойти не так, когда два значения объединены. Хеширование должно действительно использовать байтовый массив, как в зашифрованной версии, но, к сожалению, функция hash () CF9 не поддерживает его - только строки. (Хотя он плохо документирован, он поддерживается в CF11). Я не уверен, есть ли чистый обходной путь для CF9. Тем не менее, в то же время вы можете использовать Java напрямую:
<cfscript>
thePassword = "DT!@12";
base64Salt = "+muo6gAmjvvyy5doTdjyaA==";
// extract bytes of the salt and password
saltBytes = binaryDecode(base64Salt, "base64");
passBytes = charsetDecode(thePassword, "UTF-16LE" );
// next combine the bytes. note, the returned arrays are immutable,
// so we cannot use the standard CF tricks to merge them
ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
dataBytes = ArrayUtils.addAll( saltBytes, passBytes );
// hash binary using java
MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1");
MessageDigest.update(dataBytes);
theBase64Hash = binaryEncode(MessageDigest.digest(), "base64");
WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>");
WriteOutput("DBPassword= nfcqQBgeAm0Dp1oGZI0O70Y6DvA= <br />");
</cfscript>
Обновить:
Посмотрев вокруг, я не думаю, что есть чистое решение CF. Кодировка UTF-16LE - это только часть проблемы. Другая проблема заключается в том, что DNN декодирует каждую строку отдельно, что может привести к разным байтам, нежели когда оба декодируются как одна строка (см. Сравнение ниже). Это относится к вашему второму паролю, поэтому окончательный хэш отличается. поскольку hash
не будет принимать байтовые массивы, я не думаю, что это правильный инструмент для этой работы. MessageDigest
это путь
Сравнение байтовых массивов
old| new |
1 | -6 | -6 |
2 | 107 | 107 |
3 | -88 | -88 |
4 | -22 | -22 |
5 | 0 | 0 |
6 | 38 | 38 |
7 | -114 | -114 |
8 | -5 | -5 |
9 | -14 | -14 |
10 | -53 | -53 |
11 | -105 | -105 |
12 | 104 | 104 |
13 | -3 | 77 | **
14 | -1 | -40 | **
15 | 68 | -14 | **
16 | 0 | 104 | **
17 | 84 | 68 | **
18 | 0 | 0 |
19 | 33 | 84 | **
20 | 0 | 0 |
21 | 64 | 33 | **
22 | 0 | 0 |
23 | 49 | 64 | **
24 | 0 | 0 |
25 | 50 | 49 | **
26 | 0 | 0 |
27 | | 50 | **
28 | | 0 | **
- old => charsetDecode (theSalt & thePassword, "UTF-16LE")
- new => ArrayUtils.addAll (saltBytes, passBytes);