SlideShare a Scribd company logo
1 of 84
Подводные камни
прикладной криптографии I
Владимир Кочетков
Positive Technologies/Application Security Analysis Research Dept
Positive Development User Group: разрабатываем безопасно вместе
Открытое сообщество для разработчиков,
которые хотят писать безопасный код.
• Офлайн-встречи: митапы, семинары, воркшопы
• Вебинары
• Развитие бесплатной утилиты Approof
• Связаться с нами: pdug@ptsecurity.com
YouTube SlideShareFacebook
Agenda
1. 06.10.2016
a) базовые понятия,
b) высокоуровневая криптография,
c) случайные числа,
d) хэширование,
e) блочные шифры.
2. 15.12.2016
a) потоковые шифры;
b) криптография открытого ключа;
c) цифровые подписи, сертификаты, PKI;
d) защищенная передача данных, SSL/TLS;
e) протоколы аутентификации и авторизации. 4
Когда и какую криптографию
использовать?
5
Криптография обеспечивает
конфиденциальность,
целостность и аутентичность
передаваемой или хранимой
информации
6
Конфиденциальность
Состояние информационного потока, при котором доступ к нему осуществляется
только субъектами, имеющими на это право.
7
Целостность
Состояние информационного потока, при котором изменения в нём
осуществляются только субъектами, имеющими на это право.
8
Аутентичность
Состояние информационного потока, при котором подтверждается подлинность
его источника.
9
Ну, и ещё случайные числа ^_^
10
2 правила самодельной криптографии
11
Никаких самодельных алгоритмов!
Никаких самодельных реализаций!
Задача: сравнить два байтовых
массива
12
1. public static bool Equals(byte[] a1, byte[] a2)
2. {
3. if (a1.Length != a2.Length)
4. {
5. return false;
6. }
7. for (var i=0; i < first.Length; i++)
8. {
9. if (a1[i] != a2[i])
10. {
11. return false;
12. }
13. }
14. return true;
15.}
Очевидный подход
13
1. public static bool Equals(byte[] a1, byte[] a2)
2. {
3. if (a1.Length != a2.Length)
4. {
5. return false;
6. }
7. for (var i=0; i < first.Length; i++)
8. {
9. if (a1[i] != a2[i])
10. {
11. return false;
12. }
13. }
14. return true;
15.}
Очевидный подход
Если длины массивов не совпадут,
метод завершится быстрее
Время выполнения метода линейно
возрастает с ростом длины общего
префикса у a1 и a2
14
― LAN: разница в 200 наносекунд за 1000 измерений;
― Internet: разница в 30 микросекунд за 1000 измерений;
― side-channel amplification: всегда есть возможность усилить канал.
http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf
Добавление случайных временных задержек –
не работает!
https://events.ccc.de/congress/2012/Fahrplan/attachments/2235_29c3-schinzel.pdf
Timing-атаки
15
1. public static bool Equals(byte[] a1, byte[] a2)
2. {
3. var result = true;
4. for (var i = 0; i < a1.Length && i < a2.Length; ++i)
5. {
6. if (a1[i] != a2[i])
7. {
8. result = false;
9. }
10. }
11. return result;
12.}
Попытка #2 (.NET BCL-alike)
16
1. public static bool Equals(byte[] a1, byte[] a2)
2. {
3. var result = true;
4. for (var i = 0; i < a1.Length && i < a2.Length; ++i)
5. {
6. if (a1[i] != a2[i])
7. {
8. result = false;
9. }
10. }
11. return result;
12.}
Попытка #2 (.NET BCL-alike)
Нет гарантии вмешательства в поток
выполнения оптимизаторов языкового
или JIT компиляторов
17
1. public static bool Equals(byte[] a1, byte[] a2)
2. {
3. var diff = (uint)a.Length ^ (uint)b.Length;
4. for (var i = 0; i < a1.Length && i < a2.Length; i++)
5. {
6. diff |= (uint)(a1[i] ^ a2[i]);
7. }
8. return diff == 0;
9. }
Правильный подход
18
Как насчет выполнения еще
свыше десятка других правил
криптокодинга?
https://cryptocoding.net/index.php/Coding_rules
19
20
Годный план
Необходимо использовать:
― TLS для шифрования каналов передачи информации;
― существующие высокоуровневые библиотеки для всего остального:
• Sodium (https://libsodium.org – биндинги для ~40 языков);
• Keyczar (https://github.com/google/keyczar – C/C++, Java, Python, C#);
• Cryptography.io (https://cryptography.io – Python);
• Halite (https://paragonie.com/project/halite – PHP);
• … (тысячи их)
― низкоуровневую криптографию – в крайних и исключительных случаях.
21
Нельзя просто так взять и
использовать низкоуровневую
криптографию
22
Задача: обеспечить целостность
передаваемого шифротекста
23
Решение: рассчитывать подпись
по формуле signature =
HASH(secret + ciphertext) и
передавать ее вместе с
шифротекстом
24
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
25
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
26
Жестко заданный
в коде секрет
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
27
Уязвимость к атакам
удлинением сообщения
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
28
Кто сказал, что
data будет в ASCII?
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
29
Использование уязвимой
функции хэширования
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
30
Несбалансированное
сравнение строк
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
31
AES-CBC-PKCS7 →
уязвимость к атакам на
оракул дополнения
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
32
Жестко заданный в
коде ключ
Низкоуровневая криптография
1. private static bool IsValidSignature(string data, string signature)
2. {
3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data);
4. var hash = MD5.Create().ComputeHash(bytes);
5. return BitConverter.ToString(hash) == signature;
6. }
7. ...
8. if (IsValidSignature(Request["data"], Request["signature"]))
9. {
10. var decryptor = Aes.Create()
11. {
12. BlockSize = 128;
13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C");
14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R");
15. }.CreateDecryptor();
16.}
33
Жестко заданный в коде
вектор инициализации
Высокоуровневая криптография
(почувствуйте разницу)
34
Высокоуровневая криптография
1. // Keyczar (C#)
2. using(var crypter = new Crypter(keySet))
3. {
4. decryptedData = crypter.Decrypt(ciphertext);
5. }
35
Высокоуровневая криптография
1. // Keyczar (C#)
2. using(var crypter = new Crypter(keySet))
3. {
4. decryptedData = crypter.Decrypt(ciphertext);
5. }
6. // Sodium (Java)
7. SecretBox secretBox = new SecretBox(key);
8. decryptedData = secretBox.decrypt(nonce, ciphertext);
36
Высокоуровневая криптография
1. // Keyczar (C#)
2. using(var crypter = new Crypter(keySet))
3. {
4. decryptedData = crypter.Decrypt(ciphertext);
5. }
6. // Sodium (Java)
7. SecretBox secretBox = new SecretBox(key);
8. decryptedData = secretBox.decrypt(nonce, ciphertext);
9. // Halite (PHP)
10.$decryptedData = Symmetric::decrypt($ciphertext, $key);
37
Высокоуровневая криптография
1. // Keyczar (C#)
2. using(var crypter = new Crypter(keySet))
3. {
4. decryptedData = crypter.Decrypt(ciphertext);
5. }
6. // Sodium (Java)
7. SecretBox secretBox = new SecretBox(key);
8. decryptedData = secretBox.decrypt(nonce, ciphertext);
9. // Halite (PHP)
10.$decryptedData = Symmetric::decrypt($ciphertext, $key);
38
Генерация случайных чисел
39
Типичные сценарии использования PRNG
• Генерация:
—параметров криптографических функций (векторов инициализации, оказий, значений
соли, больших простых чисел и т.п.);
—идентификаторов (фрагментов файловых путей, URL);
—примитивов аутентификации (сессионных маркеров, временных паролей).
• Выбор ветви в рабочем потоке приложения.
• Специфика логики предметной области (моделирование, численный анализ).
40
А нужен ли вообще
криптографический PRNG?
41
Что, если кто-то воспроизведет
предыдущие или последующие
значения «случайной»
последовательности?
42
Внезапно, GUID не предназначен
для генерации случайных чисел
43
System.Guid (.Net Framework)
• «Черный ящик» для генерации уникальных идентификаторов → не гарантирует
случайность генерируемых GUID;
• обертка над CoCreateGuid (ole32.dll) → вызов UuidCreate (rpcrt4.dll), основанный
на RC4 и уязвимый к атакам на угадывание очередного значения
(https://rsdn.ru/article/Crypto/UuidCrypto.xml) в ряде сценариев.
44
Константное маскирование бит снижает энтропию
Использование GUID для
генерации случайных чисел
может обернуться серьезной
уязвимостью
45
Seed-гонка
- состояние приложения, при котором PRNG в различных потоках получают одно
и то же значение seed.
Эксперимент Neohapsis (http://labs.neohapsis.com/tag/seed-racing-attack-vector):
• 67 тысяч запросов на восстановление пароля;
• временный пароль генерировался с помощью
System.Random (.Net Framework);
• получено 208 ответов с уникальными паролями;
• 322 ответа содержали одинаковые пароли.
46
Уникальные Одинаковые
System.Random (.Net Framework)
• Значение seed по умолчанию Environment.TickCount → гонки за seed;
• cубтрактивный LFG(Xn = (Xn-55 - Xn-24) mod (231 - 1), n ≥ 0) → для синхронизации с
генератором достаточно получить последовательность из 55 случайных чисел;
• ошибка в реализации во всех версиях .NET вплоть до текущей → неполный цикл
случайной последовательности.
47
G(x) = x55 + x21 + 1 вместо x55 + x24 + 1
Для генерации случайных чисел
в .Net следует использовать
наследников
RandomNumberGenerator
48
System.Security.Cryptography.RandomNumberGenerator
• Абстрактный класс, в .NET BCL всего один наследник;
• RNGCryptoServiceProvider – обертка над CryptGetRandom (advapi32.dll) → FIPS-
186-2 G=SHA1 (до Windows Vista SP1) и AES-CTR (все последующие версии);
• Не требуется задавать seed для генератора Crypto API;
• Опасный метод GetNonZeroBytes снижает энтропию последовательности (после 14
нулевых бит подряд всегда будет идти единичный бит) и не должен использоваться
без необходимости;
49
Math.Random и java.util.Random (Java)
• Math.Random – обёртка над java.util.Random;
• Вычисление seed:
seed0 = (SU++) + current_timestampnano
(SU0 = 8682522807148012)
seedi+1 = (seed0^ 25214903917)&((1L << 48) - 1)
• классический LCG (Xn = (25214903917 * Xn-1 + 11) mod 248, n ≥ 0) → для
синхронизации с генератором достаточно получить последовательность из 2
случайных чисел;
50
java.security.SecureRandom
• Инкапсулирует 4 различных PRNG:
• Защищённость sun.security.provider.SecureRandom зависит от конкретной
реализации генератора
(https://www.hgi.rub.de/media/nds/veroeffentlichungen/2013/03/25/paper_2.pdf);
51
Реализация Платформа
sun.security.mscapi.PRNG Windows
sun.security.provider.nativePRNG *nix
sun.security.provider.SecureRandom Не зависит от платформы
sun.security.provider.pkcs11.P11SecureRandom N/A (PKCS)
lcg_value() (PHP)
• Вычисление seed:
Seed1 = timestamp ^ (microseconds2 << 11)
Seed2 = pid ^ (microseconds3 << 11)
• microseconds2 на 0-3 больше, чем при первом замере (microseconds1)
• pid — process id текущего процесса (0-32768)
• microseconds3 на 1-4 больше microseconds2
• Комбинированный MLCG:
→ для синхронизации с генератором достаточно получить последовательность из 3
случайных чисел;
52
mt_rand(), rand(), uniqid(), shuffle()
53
Случайные числа: take two
(https://habrahabr.ru/company/pt/blog/149746/)
Хеширование
54
HashAlgorithm (.Net Framework)
― KeyedHashAlgorithm:
• наследники HMAC?: OK (с учетом безопасности базовых хэш-функций);
• MACTripleDES: только для обратной совместимости.
― наследники MD5: не должны использоваться!
― наследники RIPEMD160: только для обратной совместимости
― наследники SHA-1: не должны использоваться!
― наследники SHA256/384/512: OK (пока)
55
Задача: обеспечить целостность
передаваемых данных
56
Решение: рассчитывать подпись
по формуле signature =
HASH(secret + data) и передавать
ее вместе с данными
57
Проблема: при таком решении
атакующий сможет подделывать
подпись data || attacker-data для
целого класса хэш-функций
58
Атака удлинением сообщения
― Подвержен ряд хэш-функций, основанных на структуре Меркла-Дамгарда:
• MD5;
• RIPEMD-160;
• SHA-1
• SHA-256;
• SHA-512.
― Не подверждены:
• SHA-384;
• HMAC-?;
• MAC-TripleDES.
59
Атака удлинением сообщения
60
Изначальное хэшируемое сообщение:
m' = m || padding
Атакующему достаточно рассчитать хэш для:
m'' = m || padding || new-data || new-padding
Используй HMAC, Люк!
61
Атака удлинением сообщения
Используй HMAC, Люк!
(ну, или data || secret)
62
Атака удлинением сообщения
Хранение паролей
63
Общие принципы
― Криптографические функции хэширования для не подходят для задачи
хранения учётных данных.
― Для хэширования паролей следует использовать адаптивные функции Argon2
(https://password-hashing.net/), PBKDF2, scrypt, bcrypt:
stored_password = salt || adaptive_hash(password, salt)
― или дайджест-функции:
stored_password = salt || HMAC-SHA-256(password, salt, secret-key)
64
Соль
― Предназначение соли — затруднение атак по словарям и радужным таблицам.
― Соль не является секретом и должна быть случайной и уникальной для каждого
пароля.
― Длина соли должна быть достаточной для обеспечения энтропии salt ||
password >= 256 бит для любого возможного пароля → длина соли >= 32
байта.
https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
65
Хранение паролей (.Net Framework)
1. public static string GetPasswordHash(string password)
2. {
3. Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 32);
4. rfc2898DeriveBytes.IterationCount = 16384;
5. byte[] hash = rfc2898DeriveBytes.GetBytes(32);
6. byte[] salt = rfc2898DeriveBytes.Salt;
7. return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
8. }
66
Хранение паролей (Java)
1. public static string getPasswordHash(final char[] password, final byte[] salt)
2. {
3. try
4. {
5. SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
6. PBEKeySpec spec = new PBEKeySpec(password, salt, 16384, 32);
7. SecretKey key = skf.generateSecret(spec);
8. byte[] res = key.getEncoded();
9. String saltString = new String(Base64.encodeBase64(salt));
10. String saltRes = new String(Base64.encodeBase64(res));
11. return saltString + "|" + saltRes;
12. }
13. catch(NoSuchAlgorithmException | InvalidKeySpecException e)
14. {
15. throw new RuntimeException(e);
16. }
17.}
67
Хранение паролей (PHP)
1. <?php
2. function get_password_hash($password)
3. {
4. return password_hash($password, PASSWORD_BCRYPT, ['cost' => 32]);
5. }
68
Блочные шифры
69
Блочные шифры
― AES: (блок 128 бит, ключ 128/192/256 бит)
― Rijndael: (блок 128/192/256 бит, ключ 128/192/256 бит)
Чтобы использовать Rijndael как AES, необходимо установить размер блока 128 бит (MCRYPT_RIJNDAEL_128 в PHP) и
не использовать режим CFB (либо использовать feedback == 128 бит).
― RC2 и TripleDES (DESede в Java): только для обратной совместимости
― DES: не должен использоваться!
― Все прочие – только при объективной необходимости
70
Критичные параметры блочных шифров
― IV – вектор инициализации:
• должен генерироваться случайным образом;
• не должен использоваться повторно;
• может не являться секретом.
― Key – ключ шифрования:
• должен генерироваться случайным образом (см. RFC 2898);
• не должен использоваться повторно;
• должен являться секретом.
71
Критичные параметры блочных шифров
― Cipher Mode - режим шифрования
• ECB: только в качестве базы для реализации неподдерживаемых режимов!
• CBC: OK, при условии дополнительной реализации EtA.
• CFB:
• OFB:
• CTS:
• CTR:
обеспечивают конфиденциальность шифротекста, основаны на IV, имитируют
потоковое шифрование, часто допускают (хотя и не требуют) дополнение.
72
73
Критичные параметры блочных шрифтов
― Padding Mode - режим дополнения блоков:
Для данных [FF FF FF FF FF FF FF FF FF]:
• ANSIX923: [FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 07]
• ISO10126: [FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07]
• None: [FF FF FF FF FF FF FF FF FF]
• PKCS7: [FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07]
• Zeros: [FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00]
74
По умолчанию все блочные
шифры в .Net используют CBC-
PKCS7
75
Проблема: если атакующий CBC-
PKCS7 сможет манипулировать
шифротекстом, отслеживая
ошибки удаления дополнения…
76
…то он сможет расшифровать
сообщение или зашифровать
произвольный текст, не владея
ключом*
77
*за исключением первого блока
78
{DEMO}
Уязвим не только конфигурация
AES-CBC-PKCS7!!!
79
Атаки на оракул дополнения
― Уязвим любой блочный шифр.
― Уязвимы все доступные режимы дополнения, кроме PaddingMode.ISO10126 и
PaddingMode.None.
― {Частично} уязвимы все доступные режимы конфиденциального шифрования,
допускающие дополнение и устанавливающие обратную связь по шифротексту
или ключевому потоку между всеми блоками (CBC, OFB, CFB, CTR, …).
― Перехват исключений и добавление временных задержек не устраняют
уязвимость.
80
Как бороться с оракулом дополнения?
― Использовать средства
высокоуровневой криптографии
― Использовать режимы аутентичного
шифрования (GCM, CWC, EAX, CCM,
OCB)
― Реализовать EtA вручную, поверх
используемого режима
81
Подход EtA (encrypt-then-authenticate)
1. Сообщение шифруется обычным образом (например, AES-CBC).
2. IV добавляется к шифротексту.
3. Для полученного на шаге 2 считается MAC с помощью одной из реализаций
HMAC (например, HMACSHA512) и также добавляется к нему.
4. …
5. Только PROFIT!!! и никаких оракулов.
82
Вопросы?
Владимир Кочетков
vkochetkov@ptsecurity.com
@kochetkov_v
Positive Technologies/Application Security Analysis Research Dept
Подводные камни прикладной криптографии, I

More Related Content

What's hot

JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...
JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...
JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...JSFestUA
 
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart GammaMongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart GammaEvgeniy Kuzmin
 
WinDbg в руках .NET разработчика
WinDbg в руках .NET разработчикаWinDbg в руках .NET разработчика
WinDbg в руках .NET разработчикаMikhail Shcherbakov
 
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)Ontico
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsPlatonov Sergey
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Yandex
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Yandex
 
Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"Mikhail Shcherbakov
 
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
 «Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus «Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus0xdec0de
 
WinDbg со товарищи
WinDbg со товарищиWinDbg со товарищи
WinDbg со товарищиCUSTIS
 
Valgrind
ValgrindValgrind
Valgrindium13
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуcorehard_by
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности PythonPyNSK
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/LinuxDefconRussia
 
CC HackQuest 2010 Full Disclosure (мастер-класс)
CC HackQuest 2010 Full Disclosure (мастер-класс)CC HackQuest 2010 Full Disclosure (мастер-класс)
CC HackQuest 2010 Full Disclosure (мастер-класс)Dmitry Evteev
 

What's hot (17)

SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
 
JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...
JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...
JS Fest 2019/Autumn. Дмитрий Жарков. Blockchainize your SPA or Integrate Java...
 
How to debug
How to debugHow to debug
How to debug
 
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart GammaMongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
 
WinDbg в руках .NET разработчика
WinDbg в руках .NET разработчикаWinDbg в руках .NET разработчика
WinDbg в руках .NET разработчика
 
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"
 
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
 «Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus «Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
 
WinDbg со товарищи
WinDbg со товарищиWinDbg со товарищи
WinDbg со товарищи
 
Valgrind
ValgrindValgrind
Valgrind
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почему
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности Python
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
 
CC HackQuest 2010 Full Disclosure (мастер-класс)
CC HackQuest 2010 Full Disclosure (мастер-класс)CC HackQuest 2010 Full Disclosure (мастер-класс)
CC HackQuest 2010 Full Disclosure (мастер-класс)
 

Similar to Подводные камни прикладной криптографии, I

Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаPositive Hack Days
 
#MBLTdev: Знакомство с codesign (e-Legion)
#MBLTdev: Знакомство с codesign (e-Legion)#MBLTdev: Знакомство с codesign (e-Legion)
#MBLTdev: Знакомство с codesign (e-Legion)e-Legion
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаAndrey Karpov
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Andrew Mayorov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеAndrey Karpov
 
Node.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчикаNode.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчикаAlexei Smolyanov
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человекаNETFest
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
Проблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахПроблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахTatyanazaxarova
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутAndrey Karpov
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
Waf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScriptWaf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScriptPositive Hack Days
 
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Vladimir Kochetkov
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибкиAndrey Karpov
 

Similar to Подводные камни прикладной криптографии, I (20)

Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
#MBLTdev: Знакомство с codesign (e-Legion)
#MBLTdev: Знакомство с codesign (e-Legion)#MBLTdev: Знакомство с codesign (e-Legion)
#MBLTdev: Знакомство с codesign (e-Legion)
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программиста
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в коде
 
Node.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчикаNode.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчика
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
Проблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахПроблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерах
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минут
 
Periculum est in mora
Periculum est in moraPericulum est in mora
Periculum est in mora
 
Scrypto designed 4
Scrypto designed 4Scrypto designed 4
Scrypto designed 4
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Waf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScriptWaf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScript
 
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 

More from Vladimir Kochetkov

Do WAFs dream of static analyzers
Do WAFs dream of static analyzersDo WAFs dream of static analyzers
Do WAFs dream of static analyzersVladimir Kochetkov
 
AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путьVladimir Kochetkov
 
Философия Application Security
Философия Application SecurityФилософия Application Security
Философия Application SecurityVladimir Kochetkov
 
Современные подходы к SAST
Современные подходы к SASTСовременные подходы к SAST
Современные подходы к SASTVladimir Kochetkov
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Vladimir Kochetkov
 
Прикладная теория Application Security
Прикладная теория Application SecurityПрикладная теория Application Security
Прикладная теория Application SecurityVladimir Kochetkov
 
Automated Patching for Vulnerable Source Code
Automated Patching for Vulnerable Source CodeAutomated Patching for Vulnerable Source Code
Automated Patching for Vulnerable Source CodeVladimir Kochetkov
 
Исключительно простая теория AppSec .NET
Исключительно простая теория AppSec .NETИсключительно простая теория AppSec .NET
Исключительно простая теория AppSec .NETVladimir Kochetkov
 
Автоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кодаАвтоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кодаVladimir Kochetkov
 
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)Vladimir Kochetkov
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Vladimir Kochetkov
 
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)Vladimir Kochetkov
 

More from Vladimir Kochetkov (12)

Do WAFs dream of static analyzers
Do WAFs dream of static analyzersDo WAFs dream of static analyzers
Do WAFs dream of static analyzers
 
AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путь
 
Философия Application Security
Философия Application SecurityФилософия Application Security
Философия Application Security
 
Современные подходы к SAST
Современные подходы к SASTСовременные подходы к SAST
Современные подходы к SAST
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible!
 
Прикладная теория Application Security
Прикладная теория Application SecurityПрикладная теория Application Security
Прикладная теория Application Security
 
Automated Patching for Vulnerable Source Code
Automated Patching for Vulnerable Source CodeAutomated Patching for Vulnerable Source Code
Automated Patching for Vulnerable Source Code
 
Исключительно простая теория AppSec .NET
Исключительно простая теория AppSec .NETИсключительно простая теория AppSec .NET
Исключительно простая теория AppSec .NET
 
Автоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кодаАвтоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кода
 
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)
How to Develop a Secure Web Application and Stay in Mind? (PHDays 3)
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
 
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
 

Подводные камни прикладной криптографии, I

  • 1.
  • 2. Подводные камни прикладной криптографии I Владимир Кочетков Positive Technologies/Application Security Analysis Research Dept
  • 3. Positive Development User Group: разрабатываем безопасно вместе Открытое сообщество для разработчиков, которые хотят писать безопасный код. • Офлайн-встречи: митапы, семинары, воркшопы • Вебинары • Развитие бесплатной утилиты Approof • Связаться с нами: pdug@ptsecurity.com YouTube SlideShareFacebook
  • 4. Agenda 1. 06.10.2016 a) базовые понятия, b) высокоуровневая криптография, c) случайные числа, d) хэширование, e) блочные шифры. 2. 15.12.2016 a) потоковые шифры; b) криптография открытого ключа; c) цифровые подписи, сертификаты, PKI; d) защищенная передача данных, SSL/TLS; e) протоколы аутентификации и авторизации. 4
  • 5. Когда и какую криптографию использовать? 5
  • 6. Криптография обеспечивает конфиденциальность, целостность и аутентичность передаваемой или хранимой информации 6
  • 7. Конфиденциальность Состояние информационного потока, при котором доступ к нему осуществляется только субъектами, имеющими на это право. 7
  • 8. Целостность Состояние информационного потока, при котором изменения в нём осуществляются только субъектами, имеющими на это право. 8
  • 9. Аутентичность Состояние информационного потока, при котором подтверждается подлинность его источника. 9
  • 10. Ну, и ещё случайные числа ^_^ 10
  • 11. 2 правила самодельной криптографии 11 Никаких самодельных алгоритмов! Никаких самодельных реализаций!
  • 12. Задача: сравнить два байтовых массива 12
  • 13. 1. public static bool Equals(byte[] a1, byte[] a2) 2. { 3. if (a1.Length != a2.Length) 4. { 5. return false; 6. } 7. for (var i=0; i < first.Length; i++) 8. { 9. if (a1[i] != a2[i]) 10. { 11. return false; 12. } 13. } 14. return true; 15.} Очевидный подход 13
  • 14. 1. public static bool Equals(byte[] a1, byte[] a2) 2. { 3. if (a1.Length != a2.Length) 4. { 5. return false; 6. } 7. for (var i=0; i < first.Length; i++) 8. { 9. if (a1[i] != a2[i]) 10. { 11. return false; 12. } 13. } 14. return true; 15.} Очевидный подход Если длины массивов не совпадут, метод завершится быстрее Время выполнения метода линейно возрастает с ростом длины общего префикса у a1 и a2 14
  • 15. ― LAN: разница в 200 наносекунд за 1000 измерений; ― Internet: разница в 30 микросекунд за 1000 измерений; ― side-channel amplification: всегда есть возможность усилить канал. http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf Добавление случайных временных задержек – не работает! https://events.ccc.de/congress/2012/Fahrplan/attachments/2235_29c3-schinzel.pdf Timing-атаки 15
  • 16. 1. public static bool Equals(byte[] a1, byte[] a2) 2. { 3. var result = true; 4. for (var i = 0; i < a1.Length && i < a2.Length; ++i) 5. { 6. if (a1[i] != a2[i]) 7. { 8. result = false; 9. } 10. } 11. return result; 12.} Попытка #2 (.NET BCL-alike) 16
  • 17. 1. public static bool Equals(byte[] a1, byte[] a2) 2. { 3. var result = true; 4. for (var i = 0; i < a1.Length && i < a2.Length; ++i) 5. { 6. if (a1[i] != a2[i]) 7. { 8. result = false; 9. } 10. } 11. return result; 12.} Попытка #2 (.NET BCL-alike) Нет гарантии вмешательства в поток выполнения оптимизаторов языкового или JIT компиляторов 17
  • 18. 1. public static bool Equals(byte[] a1, byte[] a2) 2. { 3. var diff = (uint)a.Length ^ (uint)b.Length; 4. for (var i = 0; i < a1.Length && i < a2.Length; i++) 5. { 6. diff |= (uint)(a1[i] ^ a2[i]); 7. } 8. return diff == 0; 9. } Правильный подход 18
  • 19. Как насчет выполнения еще свыше десятка других правил криптокодинга? https://cryptocoding.net/index.php/Coding_rules 19
  • 20. 20
  • 21. Годный план Необходимо использовать: ― TLS для шифрования каналов передачи информации; ― существующие высокоуровневые библиотеки для всего остального: • Sodium (https://libsodium.org – биндинги для ~40 языков); • Keyczar (https://github.com/google/keyczar – C/C++, Java, Python, C#); • Cryptography.io (https://cryptography.io – Python); • Halite (https://paragonie.com/project/halite – PHP); • … (тысячи их) ― низкоуровневую криптографию – в крайних и исключительных случаях. 21
  • 22. Нельзя просто так взять и использовать низкоуровневую криптографию 22
  • 24. Решение: рассчитывать подпись по формуле signature = HASH(secret + ciphertext) и передавать ее вместе с шифротекстом 24
  • 25. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 25
  • 26. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 26 Жестко заданный в коде секрет
  • 27. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 27 Уязвимость к атакам удлинением сообщения
  • 28. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 28 Кто сказал, что data будет в ASCII?
  • 29. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 29 Использование уязвимой функции хэширования
  • 30. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 30 Несбалансированное сравнение строк
  • 31. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 31 AES-CBC-PKCS7 → уязвимость к атакам на оракул дополнения
  • 32. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 32 Жестко заданный в коде ключ
  • 33. Низкоуровневая криптография 1. private static bool IsValidSignature(string data, string signature) 2. { 3. var bytes = Encoding.ASCII.GetBytes("eCTR4rhYQVNwn78j" + data); 4. var hash = MD5.Create().ComputeHash(bytes); 5. return BitConverter.ToString(hash) == signature; 6. } 7. ... 8. if (IsValidSignature(Request["data"], Request["signature"])) 9. { 10. var decryptor = Aes.Create() 11. { 12. BlockSize = 128; 13. Key = Encoding.ASCII.GetBytes("YtGDn6mvAHbp5X7C"); 14. IV = Encoding.ASCII.GetBytes("mHMUYSjiVxo4wp9R"); 15. }.CreateDecryptor(); 16.} 33 Жестко заданный в коде вектор инициализации
  • 35. Высокоуровневая криптография 1. // Keyczar (C#) 2. using(var crypter = new Crypter(keySet)) 3. { 4. decryptedData = crypter.Decrypt(ciphertext); 5. } 35
  • 36. Высокоуровневая криптография 1. // Keyczar (C#) 2. using(var crypter = new Crypter(keySet)) 3. { 4. decryptedData = crypter.Decrypt(ciphertext); 5. } 6. // Sodium (Java) 7. SecretBox secretBox = new SecretBox(key); 8. decryptedData = secretBox.decrypt(nonce, ciphertext); 36
  • 37. Высокоуровневая криптография 1. // Keyczar (C#) 2. using(var crypter = new Crypter(keySet)) 3. { 4. decryptedData = crypter.Decrypt(ciphertext); 5. } 6. // Sodium (Java) 7. SecretBox secretBox = new SecretBox(key); 8. decryptedData = secretBox.decrypt(nonce, ciphertext); 9. // Halite (PHP) 10.$decryptedData = Symmetric::decrypt($ciphertext, $key); 37
  • 38. Высокоуровневая криптография 1. // Keyczar (C#) 2. using(var crypter = new Crypter(keySet)) 3. { 4. decryptedData = crypter.Decrypt(ciphertext); 5. } 6. // Sodium (Java) 7. SecretBox secretBox = new SecretBox(key); 8. decryptedData = secretBox.decrypt(nonce, ciphertext); 9. // Halite (PHP) 10.$decryptedData = Symmetric::decrypt($ciphertext, $key); 38
  • 40. Типичные сценарии использования PRNG • Генерация: —параметров криптографических функций (векторов инициализации, оказий, значений соли, больших простых чисел и т.п.); —идентификаторов (фрагментов файловых путей, URL); —примитивов аутентификации (сессионных маркеров, временных паролей). • Выбор ветви в рабочем потоке приложения. • Специфика логики предметной области (моделирование, численный анализ). 40
  • 41. А нужен ли вообще криптографический PRNG? 41
  • 42. Что, если кто-то воспроизведет предыдущие или последующие значения «случайной» последовательности? 42
  • 43. Внезапно, GUID не предназначен для генерации случайных чисел 43
  • 44. System.Guid (.Net Framework) • «Черный ящик» для генерации уникальных идентификаторов → не гарантирует случайность генерируемых GUID; • обертка над CoCreateGuid (ole32.dll) → вызов UuidCreate (rpcrt4.dll), основанный на RC4 и уязвимый к атакам на угадывание очередного значения (https://rsdn.ru/article/Crypto/UuidCrypto.xml) в ряде сценариев. 44 Константное маскирование бит снижает энтропию
  • 45. Использование GUID для генерации случайных чисел может обернуться серьезной уязвимостью 45
  • 46. Seed-гонка - состояние приложения, при котором PRNG в различных потоках получают одно и то же значение seed. Эксперимент Neohapsis (http://labs.neohapsis.com/tag/seed-racing-attack-vector): • 67 тысяч запросов на восстановление пароля; • временный пароль генерировался с помощью System.Random (.Net Framework); • получено 208 ответов с уникальными паролями; • 322 ответа содержали одинаковые пароли. 46 Уникальные Одинаковые
  • 47. System.Random (.Net Framework) • Значение seed по умолчанию Environment.TickCount → гонки за seed; • cубтрактивный LFG(Xn = (Xn-55 - Xn-24) mod (231 - 1), n ≥ 0) → для синхронизации с генератором достаточно получить последовательность из 55 случайных чисел; • ошибка в реализации во всех версиях .NET вплоть до текущей → неполный цикл случайной последовательности. 47 G(x) = x55 + x21 + 1 вместо x55 + x24 + 1
  • 48. Для генерации случайных чисел в .Net следует использовать наследников RandomNumberGenerator 48
  • 49. System.Security.Cryptography.RandomNumberGenerator • Абстрактный класс, в .NET BCL всего один наследник; • RNGCryptoServiceProvider – обертка над CryptGetRandom (advapi32.dll) → FIPS- 186-2 G=SHA1 (до Windows Vista SP1) и AES-CTR (все последующие версии); • Не требуется задавать seed для генератора Crypto API; • Опасный метод GetNonZeroBytes снижает энтропию последовательности (после 14 нулевых бит подряд всегда будет идти единичный бит) и не должен использоваться без необходимости; 49
  • 50. Math.Random и java.util.Random (Java) • Math.Random – обёртка над java.util.Random; • Вычисление seed: seed0 = (SU++) + current_timestampnano (SU0 = 8682522807148012) seedi+1 = (seed0^ 25214903917)&((1L << 48) - 1) • классический LCG (Xn = (25214903917 * Xn-1 + 11) mod 248, n ≥ 0) → для синхронизации с генератором достаточно получить последовательность из 2 случайных чисел; 50
  • 51. java.security.SecureRandom • Инкапсулирует 4 различных PRNG: • Защищённость sun.security.provider.SecureRandom зависит от конкретной реализации генератора (https://www.hgi.rub.de/media/nds/veroeffentlichungen/2013/03/25/paper_2.pdf); 51 Реализация Платформа sun.security.mscapi.PRNG Windows sun.security.provider.nativePRNG *nix sun.security.provider.SecureRandom Не зависит от платформы sun.security.provider.pkcs11.P11SecureRandom N/A (PKCS)
  • 52. lcg_value() (PHP) • Вычисление seed: Seed1 = timestamp ^ (microseconds2 << 11) Seed2 = pid ^ (microseconds3 << 11) • microseconds2 на 0-3 больше, чем при первом замере (microseconds1) • pid — process id текущего процесса (0-32768) • microseconds3 на 1-4 больше microseconds2 • Комбинированный MLCG: → для синхронизации с генератором достаточно получить последовательность из 3 случайных чисел; 52
  • 53. mt_rand(), rand(), uniqid(), shuffle() 53 Случайные числа: take two (https://habrahabr.ru/company/pt/blog/149746/)
  • 55. HashAlgorithm (.Net Framework) ― KeyedHashAlgorithm: • наследники HMAC?: OK (с учетом безопасности базовых хэш-функций); • MACTripleDES: только для обратной совместимости. ― наследники MD5: не должны использоваться! ― наследники RIPEMD160: только для обратной совместимости ― наследники SHA-1: не должны использоваться! ― наследники SHA256/384/512: OK (пока) 55
  • 57. Решение: рассчитывать подпись по формуле signature = HASH(secret + data) и передавать ее вместе с данными 57
  • 58. Проблема: при таком решении атакующий сможет подделывать подпись data || attacker-data для целого класса хэш-функций 58
  • 59. Атака удлинением сообщения ― Подвержен ряд хэш-функций, основанных на структуре Меркла-Дамгарда: • MD5; • RIPEMD-160; • SHA-1 • SHA-256; • SHA-512. ― Не подверждены: • SHA-384; • HMAC-?; • MAC-TripleDES. 59
  • 60. Атака удлинением сообщения 60 Изначальное хэшируемое сообщение: m' = m || padding Атакующему достаточно рассчитать хэш для: m'' = m || padding || new-data || new-padding
  • 61. Используй HMAC, Люк! 61 Атака удлинением сообщения
  • 62. Используй HMAC, Люк! (ну, или data || secret) 62 Атака удлинением сообщения
  • 64. Общие принципы ― Криптографические функции хэширования для не подходят для задачи хранения учётных данных. ― Для хэширования паролей следует использовать адаптивные функции Argon2 (https://password-hashing.net/), PBKDF2, scrypt, bcrypt: stored_password = salt || adaptive_hash(password, salt) ― или дайджест-функции: stored_password = salt || HMAC-SHA-256(password, salt, secret-key) 64
  • 65. Соль ― Предназначение соли — затруднение атак по словарям и радужным таблицам. ― Соль не является секретом и должна быть случайной и уникальной для каждого пароля. ― Длина соли должна быть достаточной для обеспечения энтропии salt || password >= 256 бит для любого возможного пароля → длина соли >= 32 байта. https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet 65
  • 66. Хранение паролей (.Net Framework) 1. public static string GetPasswordHash(string password) 2. { 3. Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 32); 4. rfc2898DeriveBytes.IterationCount = 16384; 5. byte[] hash = rfc2898DeriveBytes.GetBytes(32); 6. byte[] salt = rfc2898DeriveBytes.Salt; 7. return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash); 8. } 66
  • 67. Хранение паролей (Java) 1. public static string getPasswordHash(final char[] password, final byte[] salt) 2. { 3. try 4. { 5. SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); 6. PBEKeySpec spec = new PBEKeySpec(password, salt, 16384, 32); 7. SecretKey key = skf.generateSecret(spec); 8. byte[] res = key.getEncoded(); 9. String saltString = new String(Base64.encodeBase64(salt)); 10. String saltRes = new String(Base64.encodeBase64(res)); 11. return saltString + "|" + saltRes; 12. } 13. catch(NoSuchAlgorithmException | InvalidKeySpecException e) 14. { 15. throw new RuntimeException(e); 16. } 17.} 67
  • 68. Хранение паролей (PHP) 1. <?php 2. function get_password_hash($password) 3. { 4. return password_hash($password, PASSWORD_BCRYPT, ['cost' => 32]); 5. } 68
  • 70. Блочные шифры ― AES: (блок 128 бит, ключ 128/192/256 бит) ― Rijndael: (блок 128/192/256 бит, ключ 128/192/256 бит) Чтобы использовать Rijndael как AES, необходимо установить размер блока 128 бит (MCRYPT_RIJNDAEL_128 в PHP) и не использовать режим CFB (либо использовать feedback == 128 бит). ― RC2 и TripleDES (DESede в Java): только для обратной совместимости ― DES: не должен использоваться! ― Все прочие – только при объективной необходимости 70
  • 71. Критичные параметры блочных шифров ― IV – вектор инициализации: • должен генерироваться случайным образом; • не должен использоваться повторно; • может не являться секретом. ― Key – ключ шифрования: • должен генерироваться случайным образом (см. RFC 2898); • не должен использоваться повторно; • должен являться секретом. 71
  • 72. Критичные параметры блочных шифров ― Cipher Mode - режим шифрования • ECB: только в качестве базы для реализации неподдерживаемых режимов! • CBC: OK, при условии дополнительной реализации EtA. • CFB: • OFB: • CTS: • CTR: обеспечивают конфиденциальность шифротекста, основаны на IV, имитируют потоковое шифрование, часто допускают (хотя и не требуют) дополнение. 72
  • 73. 73
  • 74. Критичные параметры блочных шрифтов ― Padding Mode - режим дополнения блоков: Для данных [FF FF FF FF FF FF FF FF FF]: • ANSIX923: [FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 07] • ISO10126: [FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07] • None: [FF FF FF FF FF FF FF FF FF] • PKCS7: [FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07] • Zeros: [FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00] 74
  • 75. По умолчанию все блочные шифры в .Net используют CBC- PKCS7 75
  • 76. Проблема: если атакующий CBC- PKCS7 сможет манипулировать шифротекстом, отслеживая ошибки удаления дополнения… 76
  • 77. …то он сможет расшифровать сообщение или зашифровать произвольный текст, не владея ключом* 77 *за исключением первого блока
  • 79. Уязвим не только конфигурация AES-CBC-PKCS7!!! 79
  • 80. Атаки на оракул дополнения ― Уязвим любой блочный шифр. ― Уязвимы все доступные режимы дополнения, кроме PaddingMode.ISO10126 и PaddingMode.None. ― {Частично} уязвимы все доступные режимы конфиденциального шифрования, допускающие дополнение и устанавливающие обратную связь по шифротексту или ключевому потоку между всеми блоками (CBC, OFB, CFB, CTR, …). ― Перехват исключений и добавление временных задержек не устраняют уязвимость. 80
  • 81. Как бороться с оракулом дополнения? ― Использовать средства высокоуровневой криптографии ― Использовать режимы аутентичного шифрования (GCM, CWC, EAX, CCM, OCB) ― Реализовать EtA вручную, поверх используемого режима 81
  • 82. Подход EtA (encrypt-then-authenticate) 1. Сообщение шифруется обычным образом (например, AES-CBC). 2. IV добавляется к шифротексту. 3. Для полученного на шаге 2 считается MAC с помощью одной из реализаций HMAC (например, HMACSHA512) и также добавляется к нему. 4. … 5. Только PROFIT!!! и никаких оракулов. 82