Слайд 2Disclaimer
"...Мопед не мой..."
Если вы все это знаете или думаете что это бред
![Disclaimer "...Мопед не мой..." Если вы все это знаете или думаете что](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-1.jpg)
сумасшедшего параноика - well...
Слайд 3Как мы храним пароли?
Back to Happy 90s !
Никто не заморачивается и хранит
![Как мы храним пароли? Back to Happy 90s ! Никто не заморачивается](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-2.jpg)
пароли в plain text :)
Слайд 5Пример: perlmonks & ZFO
"There is a really simple reason we owned PerlMonks:
![Пример: perlmonks & ZFO "There is a really simple reason we owned](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-4.jpg)
we couldn't resist more than 50,000 unencrypted programmer passwords."--- ZFO
979 Volma379 Tim Vroom vroom@blockstackers.com
171588 adv59416 Nigel Sandever vev6s4702@sneakemail.com
381608 archforc ELB ikegami@adaelis.com
9073 4p3rlm0n Randal L. Schwartz merlyn.perlmonk@stonehenge.com
5348 a5q!po9 Max Maischein corion@corion.net
17000 pineappl Curtis Poe curtis_ovid_poe@yahoo.com
85580 kieran Rob Kinyon rob.kinyon@gmail.com
22609 ij7dIcmy Tye McQueen nothingisobvious@gmail.com
26179 rtkJhiG2 Ben Tilly btilly@gmail.com
82147 bZ9jFSgN Tom Leete tleete@zoominternet.net
1382 p3rlm0 chromatic chromatic@wgz.org
461912 william Peter Jaquiery peter@adi.co.nz
29008 MonkEBiz david landgren david@landgren.net
169744 EahejY7f Abigail abigail@foad.org
22308 davesmit Dave Smith dws@davewsmith.co
Слайд 6Что же делать?
Hash functions to the rescue!
MD5, SHA1, SHA256, ....
X = MD5(PW)
![Что же делать? Hash functions to the rescue! MD5, SHA1, SHA256, ....](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-5.jpg)
-> храним X
Радужные таблицы?
Х = MD5(salt + PW) -> храним X и salt
Все хорошо?
Не совсем.
Слайд 7Improvements
1. Использовать случайную "соль" размером как и результат - 160 бит для
![Improvements 1. Использовать случайную "соль" размером как и результат - 160 бит](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-6.jpg)
MD5
"Bytes Are Cheap Now"
--- Bruce Schneier
2. Вместо HASH(PW+Salt) нужно использовать
HASH(HASH(PW)+Salt))
X = MD5(MD5(PW)+Salt)) -> храним X и Salt
Все теперь хорошо?
Слайд 8GPU Bruteforce
2008г. - Nvidia 8600GT - 64 млн MD5 / сек
2010г. -
![GPU Bruteforce 2008г. - Nvidia 8600GT - 64 млн MD5 / сек](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-7.jpg)
IGHASHGPU - Fastest SHA1/MD5 hash cracker on ATI and NVIDIA GPUs (с) golubev.com -
HD5770+HD4770+8600GT = 2 731 млн MD5 / сек
(в пересчете на карточку - ускорение в 10 раз за 2 года!)
Много это или мало?
8-ми символьные буквенно-цифровые пароли =
368= 2 821 109 907 456 / 2 731 000 = 20 минут (!)
(добавление спецсимволов не спасает -
528= 53 459 728 531 456 ~ 6 часов !)
Слайд 9Что делать?
Увеличивать вычислительную трудность пароля!
Вместо X=MD5(MD5(Pw)+Salt) используем
X1 = 0
Xi = MD5(Xi-1+Pw+Salt)
i
![Что делать? Увеличивать вычислительную трудность пароля! Вместо X=MD5(MD5(Pw)+Salt) используем X1 = 0](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-8.jpg)
= 1...2M
Умные люди советуют M=20 (20 бит энтропии к паролю)
Но что делать на Perl?
Цикл на 1000000 раз будет считаться довольно долго...
Сколько?
Слайд 10Проверим
use Digest::MD5 qw(md5 md5_hex);
use Benchmark;
use String::Random qw(random_string);
my $pass = random_string('.'x20);
my $salt =
![Проверим use Digest::MD5 qw(md5 md5_hex); use Benchmark; use String::Random qw(random_string); my $pass](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-9.jpg)
random_string('.'x20);
timethis(100, '
my $data = 0;
foreach (1..1024*1024) {
$data = md5($data.$pass.$salt);
}
$data = md5_hex($data.$pass.$salt);
');
Слайд 11Результаты
Для 2^20 итераций -
timethis 100: 98 wallclock secs (97.45 usr +
![Результаты Для 2^20 итераций - timethis 100: 98 wallclock secs (97.45 usr](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-10.jpg)
0.07 sys = 97.52 CPU) @ 1.03/s (n=100)
Для 2^10 итераций чуть лучше -
timethis 100000: 93 wallclock secs (92.79 usr + 0.05 sys = 92.84 CPU) @ 1077.12/s (n=100000)
Более менее-оптимально - при 2^13 итераций -
timethis 10000: 76 wallclock secs (75.32 usr + 0.02 sys = 75.34 CPU) @ 132.73/s (n=10000)
Достаточно быстро? в принципе да, но не для параноиков :) ...
Слайд 12Bcrypt to the rescue!
http://www.usenix.org/events/usenix99/provos.html
- Используется в OpenBSD c 1999г.
- Пароли по умолчанию
![Bcrypt to the rescue! http://www.usenix.org/events/usenix99/provos.html - Используется в OpenBSD c 1999г. -](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-11.jpg)
в OwlLinux и AltLinux, поддерживается в OpenSuSE и ASPLinux
- PHP Suhoshin Patch, PostgreSQL etc.
Слайд 13Features
- Основан на шифре Blowfish by Bruce Schneier
- Настраиваемый параметр вычислительной сложности
M
![Features - Основан на шифре Blowfish by Bruce Schneier - Настраиваемый параметр](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-12.jpg)
= 5 - вычисляется за 100 мс
M = 8 - вычисляется за 5 сек
Реализация
- Crypt::Eksblowfish::Bcrypt на CPAN
Слайд 14Сравним Bcrypt, MD5 и SHA512
M=8
Benchmark: timing 1000 iterations of bcrypt...
bcrypt: 25
![Сравним Bcrypt, MD5 и SHA512 M=8 Benchmark: timing 1000 iterations of bcrypt...](/_ipx/f_webp&q_80&fit_contain&s_1440x1080/imagesDir/jpg/474641/slide-13.jpg)
wallclock secs (24.91 usr + 0.00 sys = 24.91 CPU) @ 40 .14/s (n=1000)
...
M=13
Benchmark: timing 1000 iterations of md5, sha512...
md5: 8 wallclock secs ( 7.31 usr + 0.00 sys = 7.31 CPU) @ 136.80/s (n=1000)
sha512: 18 wallclock secs (18.22 usr + 0.00 sys = 18.22 CPU) @ 54.88/s (n=1000)