Искал информацию по алгоритмам оценки стойкости паролей, нашел на Хабре топик со ссылкой на Microsoft Password Checker. Как оказалось, проверка стойкости производится с помощью небольшого JS-скрипта, поэтому появилось желание подробно задокументировать алгоритм проверки. Кому-то может быть нужно прояснить, почему делается тот или иной вывод, а кому-то — улучшить алгоритм.
По следам обсуждения на Хабре, соберу основные тезисы.
Анализ кода показал, что там содержится не один, а целых два анализатора стойкости пароля — текущий, достаточно упрощенный, и старый более глубокий.
Начнем с текущего, по которому анализатор работает сейчас. Во второй части будет разбор старого.
Вывод: тривиально — не значит хорошо. Этот алгоритм совершенно не учитывает многих аспектов стойкости паролей — к примеру, словарные атаки или повторяющиеся символы.
Продолжение см. Часть 2.
По следам обсуждения на Хабре, соберу основные тезисы.
- Проверка реализована в виде passwdcheck.js.
- Эксперименты показали, что проверка не учитывает некоторых простейших вещей, которые сильно снижают стойкость.
- Рекомендации от Microsoft для создания запоминающихся сложных паролей.
Анализ кода показал, что там содержится не один, а целых два анализатора стойкости пароля — текущий, достаточно упрощенный, и старый более глубокий.
Начнем с текущего, по которому анализатор работает сейчас. Во второй части будет разбор старого.
- Уровень стойкости пароля дается в диапазоне [0; 4] в зависимости от вычисляемой «битовой стойкости» bits
- bits ≥ 128 — 4
- 128 < bits ≥ 64 — 3
- 64 < bits ≥ 56 — 2
- bits < 56 — 1
- пустой пароль — 0
- Для оценки «битовой стойкости» используется формула
гдеbits = log(charset)*(length/log(2))
- bits — битовая стойкость
- log — натуральный логарифм
- length — длина пароля
- charset — суммарный размер множеств для каждого из типов ниже, если они присутствуют в строке:
- малые английские буквы [abcdefghijklmnopqrstuvwxyz];
- заглавные английские буквы [ABCDEFGHIJKLMNOPQRSTUVWXYZ];
- специальные символы [~`!@#$%^&*()-_+="];
- цифры [1234567890];
- остальные символы
var alpha = "abcdefghijklmnopqrstuvwxyz";
var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var upper_punct = "~`!@#$%^&*()-_+=";
var digits = "1234567890";
var totalChars = 0x7f - 0x20;
var alphaChars = alpha.length;
var upperChars = upper.length;
var upper_punctChars = upper_punct.length;
var digitChars = digits.length;
var otherChars = totalChars - (alphaChars + upperChars + upper_punctChars + digitChars);
function GEId(sID) {
return document.getElementById(sID);
}
function calculateBits(passWord) {
if (passWord.length < 0) {
return 0;
}
var fAlpha = false;
var fUpper = false;
var fUpperPunct = false;
var fDigit = false;
var fOther = false;
var charset = 0;
for (var i = 0; i < passWord.length; i++) {
var char = passWord.charAt(i);
if (alpha.indexOf(char) != -1)
fAlpha = true;
else if (upper.indexOf(char) != -1)
fUpper = true;
else if (digits.indexOf(char) != -1)
fDigit = true;
else if (upper_punct.indexOf(char) != -1)
fUpperPunct = true;
else
fOther = true;
}
if (fAlpha)
charset += alphaChars;
if (fUpper)
charset += upperChars;
if (fDigit)
charset += digitChars;
if (fUpperPunct)
charset += upper_punctChars;
if (fOther)
charset += otherChars;
var bits = Math.log(charset) * (passWord.length / Math.log(2));
return Math.floor(bits);
}
function DispPwdStrength(iN, sHL) {
if (iN > 4) {
iN = 4;
}
for (var i = 0; i < 5; i++) {
var sHCR = "pwdChkCon0"; if (i <= iN) {
sHCR = sHL;
} if (i > 0) {
GEId("idSM" + i).className = sHCR;
}
GEId("idSMT" + i).style.display = ((i == iN) ? "inline" : "none");
}
}
function EvalPwdStrength(oF, sP) {
var bits = calculateBits(sP);
if (bits >= 128) {
DispPwdStrength(4, 'pwdChkCon4');
}
else if (bits < 128 && bits >= 64) {
DispPwdStrength(3, 'pwdChkCon3');
}
else if (bits<64 && bits>=56) {
DispPwdStrength(2, 'pwdChkCon2');
}
else if (bits<56) {
DispPwdStrength(1, 'pwdChkCon1');
}
else {
DispPwdStrength(0, 'pwdChkCon0');
}
}
Вывод: тривиально — не значит хорошо. Этот алгоритм совершенно не учитывает многих аспектов стойкости паролей — к примеру, словарные атаки или повторяющиеся символы.
Продолжение см. Часть 2.