Сложно объяснить всё сразу, поэтому буду делать это по частям. Сначала я расскажу то, что знаю о ключах, а потом поясню, как это относится к практике.
Я не сталкивался со старыми LPT-ключами, которые были до Stealth II и мало что про них знаю, поэтому рассматривать их не буду (да и в продаже их уже нет). Доступные сейчас ключи можно разделить на три поколения:
1. Stealth II, III - ключи с одним криптоалгоритмом (GSII64), без встроенного шифрования протокола обмена.
2. Sign – ключи имеют несколько криптоалгоритмов, в том числе ассиметричной подписи. Протокол обмена шифруется с помощью ассиметричной криптографии и разбавлен случайными «мусорными» пакетами.
3. Code – позволяют реализовать и загрузить собственные алгоритмы, а также включает в себя почти всю функциональность Sign. Протокол их обмена также шифруется.
Защита, построенная на ключах 1 и 2 поколений, с теми или иными модификациями использовала два механизма – динамическая расшифровка части программы на ключе и постоянный опрос ключа (aka схема «вопрос-ответ»).
Т.к. протокол обмена в ключах первого поколения не шифровался, то имея дампер пакетов на уровне USB-шины можно было за несколько часов активной работы с программой накопить большинство пар «вопрос-ответ» и расшифрованных блоков, которые затем вставлялись в эмулятор.
С этим можно было бороться, например, постоянно генерируя из программы случайные контрольные вопросы, а также очень частые вопросы-пустышки. Таблица дампера в этом случае становилась непомерно большой и не имела всех ответов.
Для ключей второго поколения с зашифрованным трафиком, USB-дампер выдаёт кучу шифро-мусора. А из-за того что при каждом запуске программы ключ шифрования меняется, этот мусор нельзя подсунуть программе повторно, даже если шифруемый трафик совпадает до байта. В документации я этого не нашел (может плохо искал), но разработчики уверяют, что трафик также разбавляется ложными пакетами-пустышками.
В такой защите надо бояться грамотно расставленных брекпоинтов в коде программы, особенно в тех местах, где вызывается GuardantAPI, т.к. на этой стадии контрольные вопросы ещё не зашифрованы. Помогают всё те же методы, что и с первым поколением, плюс накрыть код программы протектором. Можно использовать сторонний, а можно Guardant-овский. Опять же, если верить разработчикам, то «родной» протектор имеет свои полезные плюшки (https://www.guardant.ru/technology/monilith/). В сравнении с первым поколением для создания эмулятора придётся ковыряться в коде приложения, ища ВСЕ вызовы, сняв перед этим протектор и отключив контроль целостности API. Такая нудная работа требует значительного количества человеко-часов квалифицированного взломщика, который в свою очередь требует от заказчика значительного количества денежной массы :)
В третьем поколении можно загружать свои собственные алгоритмы, что наконец-то (аллилуйя!) позволяет реализовать защиту принципиально отличную от схемы «вопрос-ответ». Для любителей «классической миссионерской», можно конечно и по старинке, в ключе есть тот же функционал, что и в предыдущих моделях, но, на мой взгляд, это как микроскопом гвозди забивать. Трафик по-прежнему шифруется, что создаёт дополнительную трудность для анализа логики реализованной в ключе. Но опять же, на мой взгляд, при грамотном построении защиты на основе загружаемого кода, без этого шифрования можно было бы и обойтись, т.к. только тормозит общение с ключом. Видимо это было сделано из желания «подстраховать» некоторых нерадивых разработчиков защит.
P.S. Google, привёл меня вот к этой статье http://habrahabr.ru/company/aktiv-company/blog/138641/, где рассказывается о том же, но подробнее и с картинками.
Пейте сладкий чай!