Семинар: Гибридные ИТ-решения для бизнеса. 5 декабря, Санкт-Петербург

Всем привет!

Linxdatacenter и Cisco продолжают серию семинаров, посвященных практике построения гибридной ИТ-инфраструктуры. Если вы хотели, но не смогли прийти к нам в Москве, приходите в Петербурге, обещаем, что будет интересно!

Дата проведения: 5 декабря, 10:00 — 13:00
Место проведения: Санкт-Петербург, ул. Льва Толстого, д.9, бизнес-центр «Толстой Сквер», 4-й этаж, площадка «Центр событий»

О чем пойдет речь:

  • какими возможностями обладает Cisco HyperFlex,
  • что нужно принимать во внимание, выбирая ИТ-решение для бизнеса,
  • как построить гибридную ИТ-инфраструктуру: от постановки задачи до имплементации.


Программа мероприятия:

9:30-10:00 Приветственный кофе

10:00-11:15 Центр Обработки Данных от Cisco UCS – HyperFlex — Intersight.
Андрей Ларшин, менеджер по развитию бизнеса ЦОД, Cisco Россия.

11:15-11:30 Перерыв

11:30-12:00 Оптимизация ИТ-инфраструктуры под бизнес-задачи. Максим Лялин, менеджер по партнерскому взаимодействию с Cisco, Linxdatacenter.

12:00-12:30 Особенности технической имплементации гибридных ИТ-решений: опыт Linxdatacenter. Артем Клавдиев, старший инженер по ИТ и облачным сервисам, Linxdatacenter.

12:30-13:30 Фуршет

Мероприятие бесплатное, регистрация на сайте Linxdatacenter. Каждого участника ждут памятные подарки 🙂

Регистрируйтесь и приходите к нам 5 декабря!


ссылка на оригинал статьи https://habr.com/ru/company/linxdatacenter/blog/477866/

Тестирование фронтенда

Эффективная стратегия автоматизированного тестирования кода чрезвычайно важна для обеспечения быстрой и качественной работы команд программистов, занимающихся поддержкой и развитием веб-проектов. Автор статьи говорит, что в компании StackPath, в которой он работает, с тестированием сейчас всё обстоит благополучно. У них имеется множество инструментов для проверки кода. Но из такого разнообразия нужно выбрать то, что лучше всего подойдёт в каждом конкретном случае. Это — отдельная проблема. А после того, как нужные инструменты выбраны, надо ещё принять решение по поводу порядка их использования.
image
Автор материала говорит, что компанию StackPath устраивает тот уровень уверенности в качестве кода, которого удалось достичь благодаря применяемой системе тестирования. Здесь он хочет поделиться описанием принципов тестирования, выработанных в компании, и рассказать об используемых инструментах.

Принципы тестирования

Прежде чем говорить о конкретных инструментах, стоит подумать об ответе на вопрос о том, что такое хорошие тесты. До начала работы над нашим порталом для клиентов мы сформулировали и записали принципы, которым мы хотели бы следовать при создании тестов. То, что мы сделали в первую очередь именно это, помогло нам с выбором инструментов.

Вот четыре принципа, о которых идёт речь.

▍Принцип №1. Тесты следует представлять себе как задачи оптимизации

Эффективная стратегия тестирования — это решение задачи о максимизации некоего значения (в данном случае — уровня уверенности в том, что приложение будет работать правильно) и о минимизации неких затрат (здесь «затраты» представлены временем, необходимым на поддержку и запуск тестов). При написании тестов мы часто задаёмся следующими вопросами, имеющими отношение к вышеописанному принципу:

  • Какова вероятность того, что этот тест найдёт ошибку?
  • Улучшает ли этот тест нашу систему тестирования и стоят ли затраты ресурсов, необходимые на его написание, выгод, получаемых от него?
  • Можно ли получить тот же уровень уверенности в тестируемой сущности, которую даёт этот тест, создав другой тест, который легче писать, поддерживать и запускать?

▍Принцип №2. Следует избегать чрезмерного использования моков

Одно из моих любимых разъяснений понятия «мок» дано в этом выступлении с конференции Assert.js 2018. Докладчик раскрыл вопрос глубже, чем я собираюсь раскрыть его здесь. В выступлении создание моков сравнивается с «пробиванием дыр в реальности». И я думаю, что это — весьма наглядный способ восприятия моков. Хотя в наших тестах и есть моки, мы сопоставляем то снижение «стоимости» тестов, которое дают моки благодаря упрощению процессов написания и запуска тестов, с тем снижением ценности тестов, которое вызывает проделывание в реальности очередной дыры.

Раньше наши программисты сильно полагались на модульные тесты, написанные так, что все дочерние зависимости были заменены моками с использованием API неглубокого рендеринга enzyme. Отрендеренные таким образом сущности проверялись потом с использованием снапшотов Jest. Все подобные тесты были написаны с использованием сходного шаблона:

it('renders ', () => {   const wrapper = shallow();   // Если нужно, здесь можно обратиться к обёртке для получения компонента в определённом состоянии   expect(wrapper).toMatchSnapshot(); });

Подобные тесты дырявят реальность во многих местах. Этот подход позволяет очень легко достичь 100% покрытия кода тестами. При написании подобных тестов приходится очень мало размышлять, но если не проверять при этом все многочисленные точки интеграции, такие тесты оказываются не особенно ценными. Все тесты могут успешно завершиться, но вот особой уверенности в работоспособности приложения это не даёт. А ещё хуже то, что у всех моков есть скрытая «цена», которую приходится платить уже после того, как тесты написаны.

▍Принцип №3. Тесты должны способствовать рефакторингу кода, а не усложнять его

Тесты, вроде того, который показан выше, усложняют рефакторинг. Если я обнаруживаю, что во многих местах проекта имеется повторяющийся код, и через некоторое время оформляю этот код в виде отдельного компонента, то все тесты для компонентов, в которых я буду использовать этот новый компонент, дадут сбой. Компоненты, выведенные с использованием методики неглубокого рендеринга — это уже нечто иное. Там, где раньше у меня была повторяющаяся разметка, теперь присутствует новый компонент.

Более сложный рефакторинг, который подразумевает добавление в проект некоторых компонентов и удаление ещё каких-то компонентов, приводит к ещё большей путанице. Дело в том, что приходится добавлять в систему новые тесты и удалять из неё тесты ненужные. Регенерация снапшота — задача простая, но какова ценность таких тестов? Если даже они и способны найти ошибку, лучше бы они пропустили её в череде изменений снапшота и просто проверили бы новые снэпшоты, не тратя на это слишком много времени.

В результате подобные тесты не особенно помогают рефакторингу. В идеале ни один тест не должен отказать в том случае, если я выполняю рефакторинг, после которого то, что видит пользователь, и то, с чем он взаимодействует, не изменилось. И наоборот — если я поменял то, с чем контактирует пользователь, сбой должен дать хотя бы один тест. Если тесты следуют этим двум правилам, то они представляют собой отличное средство, позволяющее гарантировать то, что в ходе рефакторинга не поменялось что-то такое, с чем сталкиваются пользователи.

▍Принцип №4. Тесты должны воспроизводить то, как реальные пользователи работают с приложением

Мне хотелось бы, чтобы тесты отказывали бы только в том случае, если изменилось что-то такое, с чем взаимодействует пользователь. Это означает, что тесты должны работать с приложением так же, как с ним работают пользователи. Например, тест должен по-настоящему взаимодействовать с элементами форм и так же, как пользователь, должен вводить текст в поля для ввода текста. Тесты не должны обращаться к компонентам и самостоятельно вызывать методы их жизненного цикла, не должны писать что-то в состояние компонентов, или делать что-то такое, что опирается на тонкости реализации компонентов. Так как мне, в конечном счёте, хочется проверить ту часть системы, которая контактирует с пользователем, логично стремиться к тому, чтобы тесты при взаимодействии с системой как можно ближе бы воспроизводили действия реальных пользователей.

Инструменты тестирования

Теперь, когда мы определили цели, которых хотим достичь, давайте поговорим о том, какие инструменты мы для этого выбрали.

▍TypeScript

В нашей кодовой базе используется TypeScript. Наши бэкенд-сервисы написаны на Go и взаимодействуют друг с другом с использованием gRPC. Это позволяет нам генерировать типизированные gRPC-клиенты для использования на GraphQL-сервере. Распознаватели GraphQL-сервера типизированы с использованием типов, сгенерированных с помощью graphql-code-generator. И наконец, наши запросы, мутации, а также компоненты и хуки подписок сгенерированы полностью типизированными. Полное покрытие нашей кодовой базы типами устраняет целый класс ошибок, причиной которых является тот факт, что форма данных оказывается не такой, как ожидает программист. Генерирование типов из схемы и protobuf-файлов обеспечивает то, что вся наша система, во всех частях стека используемых технологий, остаётся однородной.

▍Jest (модульное тестирование)

В качестве фреймворка для тестирования кода мы применяем Jest и @testing-library/react. В тестах, созданных с помощью этих инструментов, мы испытываем функции или компоненты в изоляции от остальных частей системы. Мы обычно тестируем функции и компоненты, которые чаще всего используются в приложении, или такие, в которых имеется множество путей выполнения кода. Такие пути тяжело проверить в ходе интеграционного или сквозного (end-to-end, E2E) тестирования.

Модульные тесты для нас — это средство для проверки мелких деталей. Интеграционные и сквозные тесты отлично справляются с проверкой системы в более крупном масштабе, позволяют проверить общий уровень работоспособности приложения. Но иногда нужно убедиться в работоспособности мелких деталей, а писать интеграционные тесты в расчёте на все возможные варианты использования кода слишком накладно.

Например, нам нужно проверить, чтобы в компоненте, ответственном за работу с выпадающим списком, работала бы клавиатурная навигация. Но при этом нам не хотелось бы проверять все возможные варианты такого поведения при тестировании всего приложения. В результате мы тщательно тестируем навигацию в изоляции, а при тестировании страниц, использующих соответствующий компонент, обращаем внимание лишь на проверку взаимодействий более высокого уровня.

Инструменты тестирования

▍Cypress (интеграционные тесты)

Интеграционные тесты, созданные с использованием Cypress, представляют собой ядро нашей системы тестирования. Когда мы начали создавать портал StackPath, это были первые написанные нами тесты, так как они отличаются высокой ценностью при весьма небольших затратах ресурсов на их создание. Cypress выводит всё наше приложение в браузере и запускает тестовые сценарии. Весь наш фронтенд работает точно так же, как тогда, когда с ним работают пользователи. Правда, сетевой слой системы заменён моками. Каждый сетевой запрос, который в обычном условии попал бы к GraphQL-серверу, возвращает приложению условные данные.

У использования моков для имитации сетевого уровня приложения есть множество сильных сторон:

  • Тесты выполняются быстрее. Если даже бэкенд проекта отличается исключительной быстротой, время, необходимое на возврат ответов на запросы, сделанные в ходе проведения всего набора тестов, может оказаться довольно-таки существенным. А если же за возврат ответов отвечают моки, ответы возвращаются мгновенно.
  • Тесты становятся более надёжными. Одна из сложностей выполнения полного сквозного тестирования проекта заключается в том, что тут нужно принимать в расчёт изменчивое состояние сети и серверные данные, которые могут меняться. Если же реальный доступ к сети имитируется с помощью моков, эта вариабельность исчезает.
  • Легко воспроизводить ситуации, требующие точного повторения неких условий. Например, в реальной системе сложно будет сделать так, чтобы некие запросы стабильно давали бы сбой. Если нужно проверить правильность реакции приложения на неудачные запросы, то моки легко позволяют воспроизводить внештатные ситуации.

Хотя замена всего бэкенда моками и кажется непростой задачей, все условные данные типизированы с применением тех же сгенерированных TypeScript-типов, которые используются в приложении. То есть — эти данные, как минимум — в плане структуры, гарантированно эквивалентны тому, что возвратил бы обычный бэкенд. При проведении большинства тестов мы совершенно спокойно миримся с минусами использования моков вместо реальных обращений к серверам.

С Cypress, кроме того, очень приятно работать программистам. Тесты запускаются в среде запуска тестов Cypress Test Runner. Описания тестов выводятся слева, а тестируемое приложение работает в главном элементе iframe. После запуска теста можно изучить его отдельные этапы и узнать о том, как вело себя приложение в то или иное время. Так как средство для запуска тестов и само работает в браузере, для отладки тестов можно пользоваться браузерными инструментами разработчика.

При написании фронтенд-тестов часто случается так, что много времени уходит на то, чтобы сопоставить то, что делает тест, с состоянием DOM в определённый момент проведения теста. Cypress сильно упрощает эту задачу, так как разработчик может видеть всё, что происходит с тестируемым приложением. Вот видеоклип, который это демонстрирует.

Эти тесты отлично иллюстрируют наши принципы тестирования. Соотношение их ценности к их «цене» нас устраивает. Тесты очень похоже воспроизводят действия реального пользователя, взаимодействующего с приложением. А моками заменён лишь сетевой слой проекта.

▍Cypress (сквозное тестирование)

Наши E2E-тесты тоже написаны с использованием Cypress, но в них мы не используем моки ни для имитации сетевого уровня проекта, ни для имитации чего угодно другого. При выполнении тестов приложение обращается к реальному GraphQL-серверу, который работает с настоящими экземплярами бэкенд-сервисов.

Сквозное тестирование чрезвычайно ценно для нас. Дело в том, что именно результаты такого тестирования позволяют узнать о том, работает ли что-то так, как ожидалось, или не работает. Никаких моков в ходе такого тестирования не используется, в результате приложение работает точно так же, как тогда, когда им пользуются реальные клиенты. Однако надо отметить, что сквозные тесты «дороже» других. Они медленнее, их сложнее писать, учитывая возможность возникновения кратковременных сбоев в ходе их проведения. Больше работы требуется на то, чтобы обеспечить пребывание системы в известном состоянии до запуска тестов.

Тесты обычно нужно запускать в тот момент, когда система находится в некоем известном состоянии. После выполнения теста система переходит в другое известное состояние. В случае с интеграционными тестами достигнуть такого поведения системы несложно, так как обращения к API заменены моками, и, в результате, каждый запуск теста происходит в заранее известных условиях, контролируемых программистом. А вот в случае с E2E-тестами сделать это уже сложнее, так как серверное хранилище данных содержит информацию, которая в ходе проведения теста может измениться. В результате разработчику нужно найти какой-то способ обеспечения того, чтобы при запуске теста система находилась бы в заранее известном состоянии.

В начале прогона сквозных тестов мы запускаем скрипт, который, выполняя прямые обращения к API, создаёт новую учётную запись, к которой подключены стеки, сайты, рабочие нагрузки, мониторы и прочее подобное. Каждый сеанс тестирования подразумевает использование нового экземпляра подобной учётной записи, но всё остальное от случая к случаю остаётся неизменным. Скрипт, сделав всё, что нужно, формирует файл, содержащий данные, которые используются при запуске тестов (обычно там содержатся сведения об идентификаторах экземпляра и доменах). В результате оказывается, что скрипт позволяет привести в систему в заранее известное состояние до запуска тестов.

Так как сквозное тестирование «дороже» остальных видов тестирования, мы, в сравнении с интеграционными тестами, пишем меньше сквозных тестов. Мы стремимся к тому, чтобы тесты покрыли бы критически важные функции приложения. Например, это регистрация пользователей и их вход в систему, создание и настройка сайта/рабочей нагрузки, и так далее. Благодаря обширным интеграционным тестам мы знаем о том, что, в целом, наш фронтенд работоспособен. А сквозные тесты нужны лишь для того, чтобы убедиться в том, что при подключении фронтенда к бэкенду не случается что-то такое, что не способны выявить другие тесты.

Минусы нашей комплексной стратегии тестирования

Хотя мы очень довольны тестами и стабильностью приложения, у применения комплексной стратегии тестирования, подобной нашей, есть и минусы.

Для начала — применение такой стратегии тестирования означает, что все члены команды должны быть знакомы со множеством инструментов тестирования, а не только с каким-то одним. Всем нужно знать Jest, @testing-library/react и Cypress. Но при этом разработчикам не только надо знать эти инструменты. Им надо ещё и уметь принимать решения о том, в какой ситуации какой из них нужно использовать. Стоит ли для проверки некоей новой возможности писать сквозной тест, или вполне хватит интеграционного теста? Надо ли, вдобавок к сквозному или интеграционному тесту, написать модульный тест для проверки мелких деталей реализации этой новой возможности?

Несомненно, это, так сказать, «нагружает голову» наших программистов, в то время как при использовании единственного инструмента подобной нагрузки они бы не испытывали. Обычно мы начинаем с интеграционных тестов, а после этого, если видим, что исследуемая возможность отличается особой важностью и сильно зависит от серверной части проекта, добавляем соответствующий сквозной тест. Или мы начинаем с модульных тестов, делая это в том случае, если полагаем, что модульному тесту будет не под силу проверить все тонкости реализации некоего механизма.

Безусловно, мы всё ещё сталкиваемся и с такими ситуациями, когда непонятно — с чего начать. Но, по мере того, как нам постоянно приходится принимать решения, касающиеся тестов, начинают вырисовываться определённые шаблоны часто встречающихся ситуаций. Например, испытание систем валидации форм мы обычно проводим с помощью модульного тестирования. Делается это из-за того, что в ходе теста нужно проверить множество различных сценариев. При этом все в команде об этом знают и не тратят время на планирование стратегии тестирования тогда, когда кому-то из них нужно протестировать систему валидации формы.

Ещё один минус используемого нами подхода заключается в усложнении сбора данных о покрытии кода тестами. Это хотя и возможно, но куда сложнее чем в ситуации, когда для тестирования проекта используется что-то одно. Хотя погоня за красивыми цифрами покрытия кода тестами может привести к ухудшению качества тестов, подобные сведения ценны в плане поиска «дыр» в применяемом наборе тестов. Проблема использования нескольких инструментов тестирования заключается в том, что, для того, чтобы понять, какая часть кода не протестирована, нужно скомбинировать отчёты о покрытии кода тестами, полученные от разных систем. Это возможно, но это, определённо, куда сложнее, чем прочитать отчёт, сформированный каким-то одним средством для тестирования.

Итоги

При использовании множества инструментов для тестирования перед нами встали непростые задачи. Но каждый из этих инструментов служит собственной цели. В итоге мы полагаем, что поступили правильно, включив их в нашу систему тестирования кода. Интеграционные тесты — это то, с чего лучше всего начинать создание системы тестов в начале работы над новым приложением или при оснащении тестами существующего проекта. Полезно будет постараться как можно раньше добавить в проект и сквозные тесты, проверяющие самые важные возможности проекта.

Когда в наборе тестов имеются сквозные и интеграционные тесты, это должно привести к тому, что разработчик получит определённый уровень уверенности в работоспособности приложения при внесении в него каких-либо изменений. Если же в ходе работы над проектом в нём начали проявляться ошибки, которые не выявляются тестами, стоит подумать о том, какие тесты могли бы отловить эти ошибки, и о том, не указывает ли появление ошибок на недостатки всей используемой в проекте системы тестирования.

Мы, конечно, далеко не сразу пришли к сложившейся у нас системе тестирования. К тому же, мы ожидаем того, что эта система, по мере роста нашего проекта, будет развиваться. Но сейчас нам наш подход к тестированию очень нравится.

Уважаемые читатели! Каких стратегий вы придерживаетесь в области тестирования фронтенда? Какие инструменты для тестирования фронтенда вы используете?



ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/477278/

ChipWhisperer: атака по энергопотреблению на Магму

Автор статьи: rakf

В рамках Summer of Hack 2019 в Digital Security я разбирался с атакой по энергопотреблению и работал с ChipWhisperer.

Что это?

Анализ энергопотребления — это один из видов атак по сторонним каналам. То есть атак, использующих информацию, которая появляется в результате физической реализации системы.

Какая информация может быть полезна атакующему:

  • время выполнения криптопреобразований;
  • энергопотребление;
  • электромагнитные поля;
  • шум и т.д.

Атака по энергопотреблению считается наиболее универсальной.

Почему работает?

В основе микропроцессоров, микроконтроллеров, RAM и многих других логических схем лежит технология КМОП (CMOS). Потребляемая мощность КМОП-схем состоит из двух составляющих: статической и динамической. Статическое энергопотребление очень мало, что является одной из причин монополизации технологии. Динамическая мощность обусловлена переключением транзисторов и зависит от обрабатываемых данных и выполняемых операций. Поскольку статическая составляющая в основном постоянна, изменение общей мощности обусловлено исключительно динамической мощностью и, следовательно, общее энергопотребление может быть использовано для анализа.

Инструментарий

ChipWhisperer, я использовал версию с 2 частями:

ChipWhisperer 2-Part Version

ChipWhisperer – это набор инструментов с открытым исходным кодом для исследования безопасности embedded устройств. Он позволяет проводить анализ энергопотребления и атаки на основе ошибок.

Плата обойдется в $250. Разработчики позиционируют ее как революционное решение, ведь подобные комплексы, по заявлению создателей, стоят от $30k. Устройство состоит из 2 плат: целевой и платы захвата.

Существуют и другие версии, со своими преимуществами (но и за большую стоимость), также можно отдельно приобрести различные целевые платы, платы расширения, probe для полноценного анализа уже своих устройств и использования ChipWhisperer только для снятия.

У ChipWhisperer есть отличная вики, небольшие лабы для освоения, а к 5 версии даже сделали хорошую документацию по API. Трассы снимаются с подключенного устройства с помощью их ПО и записываются как NumPy массив.

Для начала необходимо написать прошивку для целевого устройства. В рамках лаб рассматриваются шифры AES, DES, TEA. Для них есть уже готовые прошивки и настройки для снятия трасс (количество отсчетов для снятия, смещение, частоту АЦП и др.). Для самостоятельного исследования настройки придется подбирать экспериментально.

Как уже сказано выше, можно спровоцировать сбой целевой платы: вызывая неисправности тактового сигнала, пропускать инструкции и извлекать секретную информацию.

В больших комплексах для снятия трасс используют осциллограф.

Анализ

Существует несколько основных методов анализа:

  • простой анализ мощности(SPA);
  • дифференциальный анализ мощности(DPA);
  • корреляционный анализ мощности(CPA).

Простой анализ мощности включает в себя визуальный анализ графика энергопотребления. Например, пароль можно получить по одному символу за раз, наблюдая профиль мощности, когда введен правильный символ, и сравнивая с неправильным.

Password power analysis

Или можно увидеть раунды шифрования на трассах. Для получения ключа данных мало, но можно предположить, какой алгоритм выполняется. На рисунке отчетливо видно 10 ранудов AES.

AES SPA

Дифференциальный анализ (DPA) гораздо эффективнее простого анализа.DPA основан на методах статистического анализа для выявления различий в следах мощности. Очень действенный инструмент, правда, для «открытия» ключа потребуется большое количество трасс. Этот метод я не использовал для анализа, но в конце дам несколько ссылок на источники, где он хорошо описан.

В основе корреляционного анализа – статистический аппарат для определения секретного ключа шифрования. Иногда его выделяют в отдельный тип, иногда относят к DPA. Этот метод требует меньшего количества трасс, чем DPA, я использовал его для анализа мощности. Расскажу о нем подробнее.

Основной задачей является построение точной модели энергопотребления исследуемого устройства. Если построена точная модель, наблюдается заметная корреляция между прогнозируемым и фактическим значением.

Одна из моделей мощности, которая может быть использована – модель веса Хэмминга. Вес Хэмминга – это количество ненулевых значений в двоичном представлении. Предположение этой модели в том, что количество битов, устанавливаемых в регистре, будет коррелировать с потребляемой устройством энергией. Сам вес Хэмминга используется в дальнейшем как условная единица энергии. Также используется модель расстояния Хэмминга — количество различных битов в 2 значениях.

Для сравнения модели веса Хэмминга и реального энергопотребления используется линейный коэффициент Пирсона. Он показывает линейную зависимость одной величины от другой. При правильно построенной модели данный коэффициент будет стремиться к 1.

Обобщенный алгоритм CPA состоит из следующих основных шагов:

  • снимаем энергопотребление при преобразовании сообщений на неизвестном ключе;
  • строим модель энергопотребления чипа при преобразовании тех же сообщений на всех возможных вариантах подблока ключа (256 вариантов для каждого байта);
  • находим коэффициент линейной корреляции для моделируемого энергопотребления и реального. В случае истинного ключа коэффициент будет стремиться к 1;
  • алгоритм повторяется для остальных подблоков ключа.

В итоге ключ восстанавливается последовательно, по небольшим частям. Если атакуем один байт ключа за раз, то используем 2 8 попыток для каждого ключа. Например, если ковырять AES — 128, то общее количество попыток для 16 байт ключа будет 212, что намного лучше, чем бить в упор 2128.

Анализ шифра Магма

Магма – это шифр, который определен в ГОСТ Р 34.12-2015, по факту тот же самый ГОСТ 28147-89, только в профиль. Шифруемый блок проходит 32 раунда, в которых происходят некоторые преобразования. Ключ состоит из 256 бит, каждый раундовый ключ представляет собой часть исходного.

Feistel function GOST

Анализировать полученные данные будем с помощью метода CPA.

Сначала необходимо выбрать промежуточное значение алгоритма, которое зависит от известных данных и небольшой части ключа и может быть рассчитано путем несложных преобразований. Обычно таким значением является выход S-box (в Магме теперь 1 таблица замен, поэтому проводить подобные атаки проще) первого (известны открытые тексты) или последнего раунда (известны шифротексты).

Я исследовал ключ с известными открытыми текстами, поэтому далее будет рассматриваться этот вариант. В алгоритме Магма, в отличие от DES, AES сложение 32-битного блока с раундовым ключом происходит по модулю 232, следовательно, лучше начинать анализ с последних выходов S-box, так как сложение старших значений никак не влияет на младшие. Рассматриваем выход каждого S-box: сначала 8, потом учитывая 8, 7 и так до первого. Снятие трасс проводилось на 8-битном микроконтроллере, и можно предположить, что он работал со сдвоенными S-box-ами. Поэтому я атаковать буду сразу по 1 байту.

Вычисление модели энергопотребления для последнего байта ключа:

    for kguess in range(0,  256):     #Initialize arrays & variables to zero     sumnum = np.zeros(numpoint)     sumden1 = np.zeros(numpoint)     sumden2 = np.zeros(numpoint)     hyp = np.zeros(numtraces)     for tnum in range(numtraces):         hyp[tnum] = HW[leak("Gost28147_tc26_ParamZ",  kguess, block2ns(text[tnum])[0], 0)]

где функция leak, просто возвращает выход S-box последнего байта.

Рассчитываем линейный коэффициент Пирсона для моделируемого и реального значения по формуле:

Correlation

    cpaoutput = [0]*256     maxcpa = [0]*256         #Mean of hypothesis         meanh = np.mean(hyp, dtype=np.float64)         #Mean of all points in trace         meant = np.mean(traces, axis=0, dtype=np.float64)         #For each trace, do the following         for tnum in range(0, numtraces):             hdiff = (hyp[tnum] - meanh)             tdiff = traces[tnum,:] - meant             sumnum = sumnum + (hdiff*tdiff)             sumden1 = sumden1 + hdiff*hdiff             sumden2 = sumden2 + tdiff*tdiff         cpaoutput[kguess] = sumnum / np.sqrt( sumden1 * sumden2 )         maxcpa[kguess] = max(abs(cpaoutput[kguess]))

При выборе истинного подключа коэффициент корреляции будет иметь значительный всплеск:

Correlation1

Таким образом анализируется каждый байт раундового ключа.

    for bnum in range(0, 4):         cpaoutput = [0]*256         maxcpa = [0]*256         for kguess in range(0,  256):             best_round_key = kguess << (bnum * 8) | best_round             ...

Учитывая первый раундовый ключ, мы можем таким же образом высчитывать 2 и последующие раундовые ключи. Полный ключ Магмы можно получить, достав 8 раундовых ключей.

В процессе решения поставленной задачи возникает несколько нюансов. В отличие от шифров AES, DES, Кузнечик, сложение раундового ключа с открытым текстом происходит по модулю 232. Сложение младших битов влияет на старшие, в отличие от XORa. При расчете каждого следующего подключа приходится учитывать результаты прошлого. Аналогично и с раундовыми ключами. Данные очень чувствительны. При неправильном расчете одного из значений дальнейший расчет всего ключа будет неправильным.

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

Для выполнения шифра DES такой криптопроцессор может иметь шестиразрядную архитектуру, для «Магмы» — четырехразрядную, что позволяет обрабатывать каждый S-box отдельно. Мое целевое устройство 8-битное, и в случае «Магмы» за один подход будет производиться преобразование над восьмью битами, т.е. замена будет происходить на 2 S-box, энергопотребление будет считаться для 2 S-box. Если один из S-box, старший или младший, совпадает с истинным ключом, а другой не совпадает, могут возникать высокие корреляционные всплески.

Учитывая все вышесказанное, на выходе имеем следующий скрипт для анализа трасс энергопотребления для шифра Магма:

Скрипт на Python

    import numpy as np     path = r'C:\Users\user\chipwhisperer\projects\gost_10000_2_data\traces\2019.08.11-19.53.25_'     traces = np.load(path + 'traces.npy')     text   = np.load(path + 'textin.npy')     keys   = np.load(path + 'keylist.npy')     HW = [bin(n).count("1") for n in range(0,256)]     SBOXES = {"Gost28147_tc26_ParamZ": (             (12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1),             (6, 8, 2, 3, 9, 10, 5, 12, 1, 14, 4, 7, 11, 13, 0, 15),             (11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0),             (12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11),             (7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12),             (5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0),             (8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7),             (1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2),         )}      def _K(s, _in):         """ S-box substitution         :param s: S-box         :param _in: 32-bit word         :returns: substituted 32-bit word         """         return (             (s[0][(_in >> 0) & 0x0F] << 0) +             (s[1][(_in >> 4) & 0x0F] << 4) +             (s[2][(_in >> 8) & 0x0F] << 8) +             (s[3][(_in >> 12) & 0x0F] << 12) +             (s[4][(_in >> 16) & 0x0F] << 16) +             (s[5][(_in >> 20) & 0x0F] << 20) +             (s[6][(_in >> 24) & 0x0F] << 24) +             (s[7][(_in >> 28) & 0x0F] << 28)         )     def block2ns(data):         """ Convert block to N1 and N2 integers         """         data = bytearray(data)         return (             data[7] | data[6] << 8 | data[5] << 16 | data[4] << 24,             data[3] | data[2] << 8 | data[1] << 16 | data[0] << 24,         )     def addmod(x, y, mod=2 ** 32):         """ Modulo adding of two integers         """         r = x + int(y)         return r if r < mod else r - mod     def _shift11(x):         """ 11-bit cyclic shift         """         return ((x << 11) & (2 ** 32 - 1)) | ((x >> (32 - 11)) & (2 ** 32 - 1))     def round(sbox, key, data, byte):         s = SBOXES[sbox]         _in = addmod(data, key)         sbox_leak = _K(s, _in);         return (sbox_leak >> (8 * byte)) & 0xFF     def Feistel(sbox, key, data, nround):         s = SBOXES[sbox]         w = bytearray(key)         x = [             w[3 + i * 4] |             w[2 + i * 4] << 8 |             w[1 + i * 4] << 16 |             w[0 + i * 4] << 24 for i in range(8)         ]         n1, n2 = block2ns(data)         for i in range(nround):             n1, n2 = _shift11(_K(s, addmod(n1, x[i]))) ^ n2, n1         return n1     numtraces = len(traces)     numpoint = np.shape(traces)[1]     bestguess = [0]*32     round_data = [0] * numtraces     for i in range(numtraces):         round_data[i] = [0] * 8     for rnum in range(0, 8):         best_round = 0         for tnum_r in range(numtraces):             round_data[tnum_r][rnum] = Feistel("Gost28147_tc26_ParamZ", bestguess, text[tnum_r], rnum)         for bnum in range(0, 4):             cpaoutput = [0]*256             maxcpa = [0]*256             for kguess in range(0,  256):                 #Initialize arrays & variables to zero                 best_round_key = kguess << (bnum * 8) | best_round                 sumnum = np.zeros(numpoint)                 sumden1 = np.zeros(numpoint)                 sumden2 = np.zeros(numpoint)                 hyp = np.zeros(numtraces)                 for tnum in range(numtraces):                     hyp[tnum] = HW[round("Gost28147_tc26_ParamZ",  best_round_key, round_data[tnum][rnum], bnum)]                 #Mean of hypothesis                 meanh = np.mean(hyp, dtype=np.float64)                 #Mean of all points in trace                 meant = np.mean(traces, axis=0, dtype=np.float64)                 #For each trace, do the following                 for tnum in range(0, numtraces):                     hdiff = (hyp[tnum] - meanh)                     tdiff = traces[tnum,:] - meant                     sumnum = sumnum + (hdiff*tdiff)                     sumden1 = sumden1 + hdiff*hdiff                     sumden2 = sumden2 + tdiff*tdiff                 cpaoutput[kguess] = sumnum / np.sqrt( sumden1 * sumden2 )                 maxcpa[kguess] = max(abs(cpaoutput[kguess]))             best_round = best_round | (np.argmax(maxcpa) << (bnum * 8))             bestguess[((rnum + 1) * 4)-bnum - 1] = np.argmax(maxcpa)     print "Best Key Guess: "     for b in bestguess: print "%02x "%b,

Репозиторий с результатами на GitHub

Выводы

В рамках исследования я работал с ChipWhisperer. Несмотря на то, что я попробовал не все инструменты (например, глитчинг), я однозначно нахожу ChipWhisperer полезным, особенно если не хочется покупать дорогое специальное железо.

Что касается анализа нашего шифра на энергопотребление, то он устойчивее к данной атаке, чем описанные выше шифры, но при достаточном количестве данных ключ можно достать без проблем.

Интересные материалы:


ссылка на оригинал статьи https://habr.com/ru/company/dsec/blog/477730/

Доживем до понедельника или как пережить чёрную пятницу

Завтра «Черная Пятница» — для интернет проектов это означает, что будут пиковые нагрузки на сайт. Их могут не выдержать даже гиганты, так например, случилось с Amazon в Prime Day в 2017 году. 

Мы решили привести несколько простых примеров работы с виртуальным сервером, чтобы избежать ошибок и не встречать народ 503 страницей или что еще хуже, About:blank и ERR_CONNECTION_TIMED_OUT. Остаётся один день, чтобы подготовиться.

Масштабирование ресурсов

Сайт обычно состоит из разных модулей — базы данных, веб-сервера, системы кэширования. Каждый из этих модулей требует различные типы и объемы ресурсов. Необходимо заранее провести анализ объема потребляемых ресурсов с помощью стресс-тестов и оценить скорость ввода-вывода дисков, процессорное время, память, ширину интернет полосы вашего сайта.

Стресс-тесты помогут определить узкие места вашей системы и заранее их масштабировать. Так, например, вы можете улучшить мощность вашего сервера за счет увеличения места на жестком диске на время проведения акции, расширить полосу сайта или увеличить оперативную память виртуального сервера. После акции можно вернуть все как было, делается это в личном кабинете без обращения в техподдержку и занимает пару минут, но лучше это делать заранее и в часы минимальной активности клиентов на сайте.

Заранее защититься от DDoS-атак

Сайты в дни распродаж падают не только из-за роста притока клиентов, но из за DDoS-атак. Их могут организовать злоумышленники, которые хотят перенаправить ваш трафик на свои фишинговые ресурсы. 

DDoS-атаки с каждым днем становятся все более изощреннее. Хакеры используют различные подходы, прибегая одновременно к DDoS-атакам и атакам на уязвимости приложений. В большинстве случаев атаки сопровождаются попытками взлома сайта.

Здесь также важно заранее подготовиться и подключить к вашему серверу защищенный от атак IP адрес. В UltraVDS мы защищаем серверы не по факту атаки, а круглосуточно и стабильно выдерживаем атаки до 1.5 Tbps! Для защиты серверов от DDoS-атак применяется серия фильтров, подключенных к интернет-каналу с достаточно большой пропускной способностью. Фильтры последовательно анализируют проходящий трафик, выявляя аномалии и нестандартную сетевую активность. В число анализируемых шаблонов нестандартного трафика входят все известные на сегодняшний день методы атак, в том числе реализуемые при помощи распределенных бот-сетей.

Для подключения защищенного адреса к виртуальному серверу необходимо отправить заявку в службу поддержки провайдера заранее.

Ускорить загрузку сайта

В периоды проведения акций повышается нагрузка на серверы, на сайтах начинают долго грузиться фото и карточки товаров. Также загрузку страниц утяжеляют различные фреймворки, JS-библиотеки, CSS модули и так далее. Потенциальный клиент может уйти со страницы, не получив ответа от сайта, даже в случае более выгодного предложения, чем у конкурентов. Для проверки скорости загрузки страниц предлагаем использовать Google DevTools.

Помочь ускорить загрузку страниц способна сеть доставки контента (Content Delivery Network, CDN). CDN это географически распределенная сеть, которая состоит из кэширующих узлов — точек присутствия, они могут находиться по всему миру. При заходе на сайт, клиент будет получать статический контент не от вашего сервера, а от того, который входит в CDN-сеть и находится ближе к нему. Благодаря сокращению маршрута между сервером и клиентом данные на сайте грузятся быстрее.

CDN-сеть можно настроить самому, если у вас есть VDS на Windows Server Core 2019, для этого использовать встроенные в операционную систему средства такие как: Active Directory, DFS, IIS, WinAcme, RSAT. Можно также использовать готовые решения, например, CDN от Cloudflare могла бы решить задачу существенно быстрее и дешевле. Плюс у данной системы есть дополнительные возможности: DNS, сжатие HTML, CSS, JS, много точек присутствия.

Удачных вам продаж.

Чёрная пятница в UltraVDS

Мы также не прошли мимо традиционных скидок в этот день и предлагаем пользователям Хабра промокод BlackFr со скидкой 15% на все наши виртуальные серверы с 28 ноября по 2 декабря включительно.

Например, VDS сервер по тарифу UltraLight с 1 ядром CPU, 500МБ оперативной памяти и 10ГБ дискового пространства под управлением Windows Server Core 2019 можно приобрести по промокоду BlackFr с дополнительной 30% скидкой на год всего за 55 рублей в месяц, таким образом суммарная скидка составит 45% от текущей цены.

UltraVDS — современный облачный провайдер, с нами работают сотни крупных организаций, в числе которых известные банки, биржевые брокеры, строительные и фармацевтические компании. 


ссылка на оригинал статьи https://habr.com/ru/company/ultravds/blog/477824/

Как состязательные игры помогают работать эффективнее

Я играю в компьютерные игры с пяти лет. Первой моей игрой стала GTA, вышедшая в 2001 году, которая тогда была чем-то вроде того, что представляет собой Fortnite сегодня, только оффлайн и намного менее социальная. Со временем я вырос и увлекся играми, требующими стратегического мышления: World of Warcraft, Battlefield и Call of Duty. Единственной игрой, в которую я играл профессионально (и участвовал в турнирах), была Counter-Strike.

Игры для меня никогда не были способом построить карьеру, но я по-прежнему играю: это дает мне эмоциональный подъем и возбуждает мозговую активность.

В обычной жизни я никогда не замечал за собой такой сообразительности и такого волнения, которые бывают на киберспортивных соревнованиях.

Сейчас мне 23 года, я работаю старшим аналитиком в компании, которая работает с данными и исследует экосистему блокчейна для инвестиционных фирм и корпоративных клиентов. И, должен признаться, часть моих достижений и в обычной, и в профессиональной жизни тесно связана с умственными навыками, которые я приобрел, играя в Counter-Strike.

Состязательные игры помогли мне стать более трудоспособным и сделали меня лучше в целом — и на это есть пять причин.

Переведено в Alconost


Фото — Anthony Brolin, площадка Unsplash

Командная игра

Игры

В состязательных играх главное — это хорошая и честная командная работа. На соревнованиях по киберспорту важно понимать своих товарищей по команде, знать, что они чувствуют, и играть вместе ради достижения одной цели. В играх можно выбрать: или вы хороши сами по себе, или великолепны в команде.

Чтобы добиться успеха и собрать отличную команду, нужно хорошо узнать друг друга — посредством общения, споров, общих побед и преодоления трудностей.

Реальная жизнь.

Работа отчасти похожа на игру, поэтому если вы стремитесь к наибольшему успеху, единственный способ его достичь — с помощью товарищей по команде.

Для меня главным приоритетом было узнать коллег глубже и научиться их понимать. Благодаря этому я намного быстрее завоевал их доверие, мне стало проще делиться своими мыслями и участвовать в сложных проектах.


Фото — Mario Gogh, площадка Unsplash

Работа в стрессовой ситуации

Игры

В играх эмоции бьют через край: иногда они приятные (если вы побеждаете), иногда — наоборот (если побеждают вас). На соревнованиях второй возможности не дается: проиграв матч, вы покидаете турнир — и понимание этого сильно давит. Однако нужно сохранять спокойствие и помнить, что у вас есть шанс выиграть и пройти дальше.

Реальная жизнь

Это же применимо и к нашей повседневной жизни, в том числе к работе. Иногда всё идет хорошо, вам удается проявить себя, и вас хлопают вас по плечу, поздравляя с успехами. Но бывает и наоборот: ничего не получается, и ты чувствуешь себя неудачником. Постоянные трудности на работе — знакомая многим картина. Умение днями работать под психическим давлением — ценный навык, который я приобрел в играх.

Сохраняйте спокойствие и оставайтесь в игре!

Умение быстро думать и мгновенно принимать решения

Игры

Время в играх — один из самых ценных ресурсов. Раунд в игре Counter-Strike длится менее двух минут (1:55), и за это время успевает произойти множество непредсказуемых событий. В состязательной игре очень важна способность быстро обрабатывать информацию и мгновенно реагировать. Не каждый сможет застать противника врасплох, применив быстрое аналитическое мышление, поэтому умение принимать решения быстро и уверенно — признак хорошего игрока.

Реальная жизнь

В обычной жизни полно непредсказуемых переменных, не поддающихся контролю. Готовность действовать быстро и мгновенно находить решение определенной задачи или правильно реагировать на определенное событие — ценный навык, который пригодится везде: не только на работе, но и в повседневной жизни.

Творческое мышление: думай как противник (или как клиент)

Игры

В состязательных играх рассуждаешь примерно так: «Окажись я на месте противника, чего бы я ожидал сейчас?» Вы пытаетесь предсказать следующий ход оппонента и стараетесь застать его врасплох. Умение предсказывать чужие действия — важный навык: так вы можете сделать что-то неожиданное, что в итоге приведет к победе.

Реальная жизнь

Многие работодатели зачастую ищут кандидатов, способных к нестандартному мышлению, и ценят людей, способных находить творческие решения сложных задач. Творческие способности — уникальная человеческая черта, скопировать которую роботы не способны. Именно она помогает найти гораздо более увлекательный, быстрый и надежный путь из условного пункта А в условный пункт Б.

Возможность отвлечься

У игрока естественным образом появляется способ отключиться от остального мира. На мой взгляд, это одна из самых важных потребностей, и у каждого должна быть возможность удовлетворить ее: «подзарядиться» и не съехать с катушек. Слишком уж часто мне доводилось наблюдать, как другие буквально сходят с ума из-за долгих часов на работе, чрезмерной загрузки и бесконечной очереди электронных писем. Игры для меня — это простой и полезный способ отключиться от мира на часок-другой и забыть обо всех проблемах.

О переводчике

Перевод статьи выполнен в Alconost.

Alconost занимается локализацией игр, приложений и сайтов на 70 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.

Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.

→ Подробнее


ссылка на оригинал статьи https://habr.com/ru/company/alconost/blog/477878/