Как я могу зашифровать байты с помощью модуля TPM машины?
CryptProtectData
Windows предоставляет (относительно) простой API для шифрования большого двоичного объекта с помощью CryptProtectData
API, который мы можем обернуть простой в использовании функцией:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Детали ProtectBytes
менее важны, чем идея о том, что вы можете легко использовать это:
- вот байты, которые я хочу зашифровать секретным ключом, хранящимся в
System
- верните мне зашифрованный blob
Возвращенный блоб недокументированная документация структура , которая содержит все необходимое для расшифровки и вернуть исходные данные (хэш - алгоритм, алгоритм шифрования, соль, HMAC подписи и т.д.).
Для полноты, вот пример реализации псевдокода, ProtectBytes
который использует Crypt API
для защиты байтов:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//Setup our n-byte plaintext blob
DATA_BLOB dataIn;
dataIn.cbData = plaintext.Length;
dataIn.pbData = Addr(plaintext[0]);
DATA_BLOB dataOut;
//dataOut = EncryptedFormOf(dataIn)
BOOL bRes = CryptProtectData(
dataIn,
null, //data description (optional PWideChar)
null, //optional entropy (PDATA_BLOB)
null, //reserved
null, //prompt struct
CRYPTPROTECT_UI_FORBIDDEN || CRYPTPROTECT_LOCAL_MACHINE,
ref dataOut);
if (!bRes) then
{
DWORD le = GetLastError();
throw new Win32Error(le, "Error calling CryptProtectData");
}
//Copy ciphertext from dataOut blob into an actual array
bytes[] result;
SetLength(result, dataOut.cbData);
CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);
//When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Как сделать то же самое с TPM?
Приведенный выше код полезен для шифрования данных только на локальном компьютере. Данные зашифрованы с использованием System
учетной записи в качестве генератора ключей ( подробности хоть и интересны, но не важны ). Конечным результатом является то, что я могу зашифровать данные (например, главный ключ шифрования жесткого диска), которые могут быть расшифрованы только на локальной машине.
Пришло время сделать еще один шаг вперед. Я хочу зашифровать некоторые данные (например, главный ключ шифрования жесткого диска), которые могут быть расшифрованы только локальным TPM. Другими словами, я хочу заменить Qualcomm Trusted Execution Environment ( TEE ) на блок-схеме ниже для Android на TPM в Windows:
Примечание . Я понимаю, что TPM не выполняет подписывание данных (или, если это так, он не гарантирует, что подписание одних и тех же данных будет давать одинаковый двоичный вывод каждый раз). Вот почему я хотел бы заменить «подпись RSA» на «шифрование 256-битного BLOB-объекта с помощью аппаратного ключа» .
Так где же код?
Проблема в том, что программирование TPM полностью недокументировано в MSDN . API для выполнения каких-либо операций отсутствует. Вместо этого вам нужно найти себе копию стека программного обеспечения Trusted Computing Group (также известного как TSS) , выяснить, какие команды отправлять в TPM с полезными данными , в каком порядке, и вызвать функцию Window Tbsip_Submit_Command для непосредственной отправки команд:
TBS_RESULT Tbsip_Submit_Command(
_In_ TBS_HCONTEXT hContext,
_In_ TBS_COMMAND_LOCALITY Locality,
_In_ TBS_COMMAND_PRIORITY Priority,
_In_ const PCBYTE *pabCommand,
_In_ UINT32 cbCommand,
_Out_ PBYTE *pabResult,
_Inout_ UINT32 *pcbOutput
);
В Windows нет API более высокого уровня для выполнения действий.
Это моральный эквивалент попытки создать текстовый файл с помощью команд ввода-вывода SATA на ваш жесткий диск .
Почему бы просто не использовать брюки
Группа Trusted Computing Group (TCG) действительно определила свой собственный API: TCB Software Stack (TSS) . Реализация этого API была создана некоторыми людьми и называется TrouSerS . Затем один парень перенес этот проект на Windows .
Проблема с этим кодом в том, что он не переносится в мир Windows. Например, вы не можете использовать его из Delphi, вы не можете использовать его из C #. Это требует:
- OpenSSL
- pThread
Я просто хочу, чтобы код что-то зашифровал с помощью моего TPM.
Вышеупомянутое не CryptProtectData
требует ничего, кроме того, что находится в теле функции.
Каков эквивалентный код для шифрования данных с помощью TPM? Как отмечали другие, вам, вероятно, придется проконсультироваться с тремя руководствами по TPM и самостоятельно построить большие двоичные объекты . Вероятно, это связано с TPM_seal
командой. Хотя я думаю, что не хочу запечатывать данные, я думаю, что хочу их привязать :
Привязка - данные шифруются с использованием ключа привязки TPM, уникального ключа RSA, производного от ключа хранилища. Запечатывание - шифрует данные аналогично привязке, но дополнительно указывает состояние, в котором должен находиться TPM, чтобы данные были расшифрованы (распечатаны).
Я пытаюсь прочитать три необходимых тома, чтобы найти 20 строк кода, которые мне нужны:
Но я понятия не имею, что читаю. Если бы был какой-нибудь учебник или примеры, я мог бы попробовать. Но я совершенно потерялся.
Итак, мы просим Stackoverflow
Таким же образом я смог предоставить:
Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
//...
CryptProtectData(...);
//...
}
может кто-нибудь предоставить соответствующий эквивалент:
Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
//...
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
//...snip...
Tbsip_Submit_Command(...);
//...
}
что делает то же самое, за исключением того, что ключ, заблокированный в System
LSA, заблокирован в TPM?
Начало исследования
Я точно не знаю, что означает привязка . Но, глядя на TPM Main - Part 3 Commands - Specification Version 1.2, есть упоминание bind :
10.3 TPM_UnBind
TPM_UnBind берет большой двоичный объект данных, который является результатом команды Tspi_Data_Bind, и расшифровывает его для экспорта пользователю. Вызывающий должен разрешить использование ключа, который будет расшифровывать входящий большой двоичный объект. TPM_UnBind работает на поблочной основе и не имеет представления о какой-либо связи между одним блоком и другим.
Что толку там нет нет Tspi_Data_Bind
команды.
Исследовательские усилия
Ужасно, что никто никогда не удосужился задокументировать TPM или его работу. Как будто они потратили все свое время на то, чтобы поиграть с этой классной вещью , но не хотели иметь дело с болезненным шагом, чтобы сделать ее пригодной для чего-то.
Начиная с (сейчас) бесплатной книги A Practical Guide to TPM 2.0: Using the Trusted Platform Module in the New Age of Security :
Глава 3 - Краткое руководство по TPM 2.0
TPM имеет доступ к собственному закрытому ключу, поэтому он может шифровать ключи с помощью открытого ключа, а затем сохранять полученный большой двоичный объект на жестком диске. Таким образом, TPM может хранить практически неограниченное количество ключей, доступных для использования, но не тратить впустую ценное внутреннее хранилище. Ключи, хранящиеся на жестком диске, можно стереть, но также можно сделать резервную копию, что казалось дизайнерам приемлемым компромиссом.
Как я могу зашифровать ключ с помощью открытого ключа TPM?
Глава 4 - Существующие приложения, использующие TPM
Приложения, которые должны использовать TPM, но не должны
За последние несколько лет количество веб-приложений увеличилось. Среди них - резервное копирование и хранение через Интернет. Многие компании сейчас предлагают такие услуги, но, насколько нам известно, ни один из клиентов этих услуг не позволяет пользователю заблокировать ключ для службы резервного копирования на TPM. Если бы это было сделано, было бы неплохо, если бы для самого ключа TPM была создана резервная копия, дублируя его на нескольких машинах. Кажется, это возможность для разработчиков.
Как разработчик блокирует ключ к TPM?
Глава 9 - Heirarchies
СЛУЧАЙ ИСПОЛЬЗОВАНИЯ: СОХРАНЕНИЕ ПАРОЛЕЙ ВХОДА
Типичный файл паролей хранит соленые хэши паролей. Проверка состоит из посоления и хеширования предоставленного пароля и сравнения его с сохраненным значением. Поскольку в расчет не входит секрет, он может подвергнуться атаке в автономном режиме на файл паролей.
В этом варианте использования используется ключ HMAC, созданный TPM. Файл паролей хранит HMAC солидного пароля. Проверка состоит из обработки и HMAC предоставленного пароля и сравнения его с сохраненным значением. Поскольку у автономного злоумышленника нет ключа HMAC, злоумышленник не может организовать атаку, выполнив расчет.
Это могло сработать. Если доверенный платформенный модуль имеет секретный ключ HMAC, и только мой доверенный платформенный модуль знает этот ключ HMAC, то я могу заменить «Подписать (он же TPM, зашифрованный с его закрытым ключом)» на «HMAC». Но затем в следующей строке он полностью меняет свое мнение:
TPM2_Create, указав ключ HMAC
Если мне нужно указать ключ HMAC, это не секрет TPM. Тот факт, что ключ HMAC не является секретным, имеет смысл, если вы понимаете, что это глава о криптографических утилитах, которые предоставляет TPM. Вместо того, чтобы вам самому писать SHA2, AES, HMAC или RSA, вы можете повторно использовать то, что уже есть в TPM.
Глава 10 - Ключи
В качестве устройства безопасности способность приложения использовать ключи, сохраняя их в безопасности на аппаратном устройстве, является самой сильной стороной TPM. TPM может как генерировать, так и импортировать ключи, созданные извне. Он поддерживает как асимметричные, так и симметричные ключи.
Превосходно! Как ты это делаешь!?
Генератор ключей
Возможно, самая сильная сторона TPM - это его способность генерировать криптографический ключ и защищать свой секрет в пределах аппаратного обеспечения. Генератор ключей основан на собственном генераторе случайных чисел TPM и не зависит от внешних источников случайности. Таким образом устраняются слабые места, основанные на слабом программном обеспечении с недостаточным источником энтропии.
Имеет ли TPM возможность генерировать криптографические ключи и защищать свои секреты в пределах аппаратного обеспечения? Так как?
Глава 12 - Регистры конфигурации платформы
PCR для авторизации
СЛУЧАЙ ИСПОЛЬЗОВАНИЯ: ЗАПЕЧАТАНИЕ КЛЮЧА ДЛЯ ШИФРОВАНИЯ ЖЕСТКОГО ДИСКА ДЛЯ СОСТОЯНИЯ ПЛАТФОРМЫ
Приложения полнодискового шифрования намного безопаснее, если TPM защищает ключ шифрования, чем если он хранится на том же диске и защищен только паролем. Во-первых, оборудование TPM имеет защиту от взлома (см. Главу 8 для подробного описания защиты от атак по словарю TPM), что делает непрактичную атаку методом перебора пароля. Ключ, защищенный только программным обеспечением, гораздо более уязвим для слабого пароля. Во-вторых, программный ключ, хранящийся на диске, гораздо легче украсть. Возьмите диск (или резервную копию диска), и вы получите ключ. Когда TPM хранит ключ, вся платформа или, по крайней мере, диск и материнская плата должны быть украдены.
Запечатывание позволяет защитить ключ не только паролем, но и политикой. Типичная политика блокирует ключ к значениям PCR (состоянию программного обеспечения), текущим на момент запечатывания. Это предполагает, что состояние при первой загрузке не нарушено. Любая предустановленная вредоносная программа, присутствующая при первой загрузке, будет измеряться в PCR, и, таким образом, ключ будет запечатан для состояния скомпрометированного программного обеспечения. У менее доверчивого предприятия может быть стандартный образ диска и печать на PCR, представляющих этот образ. Эти значения PCR будут предварительно рассчитаны на предположительно более надежной платформе. Даже более сложное предприятие могло бы использовать TPM2_PolicyAuthorize и предоставить несколько билетов, авторизующих набор доверенных значений PCR. См. Главу 14 для подробного описания политики авторизации и ее применения для решения проблемы уязвимости PCR.
Хотя пароль также может защитить ключ, есть выигрыш в безопасности даже без пароля ключа TPM. Злоумышленник может загрузить платформу без ввода пароля TPMkey, но не может войти в систему без имени пользователя и пароля ОС. OSsecurity защищает данные. Злоумышленник может загрузить альтернативную ОС, например, с живого DVD или USB-накопителя, а не с жесткого диска, чтобы обойти безопасность входа в ОС. Однако эта другая конфигурация загрузки и программное обеспечение могут изменить значения PCR. Поскольку эти новые PCR не будут соответствовать запечатанным значениям, TPM не выпустит ключ дешифрования, и жесткий диск не сможет быть расшифрован.
Превосходно! Это именно тот вариант использования, который мне и нужен. Также в этом случае Microsoft использует TPM. Как мне это сделать!?
Я прочитал эту книгу полностью, и ничего полезного в ней не было. Что очень впечатляет, потому что это 375 страниц. Вам интересно, что было в книге - и, оглядываясь назад, я понятия не имею.
Поэтому мы отказываемся от исчерпывающего руководства по программированию TPM и вместо этого обращаемся к некоторой документации от Microsoft:
Из набора средств криптографического провайдера платформы TPM Microsoft . В нем точно указано, что я хочу делать:
Ключ подтверждения или EK
EK предназначен для обеспечения надежного криптографического идентификатора для платформы. Предприятие может вести базу данных ключей подтверждения, принадлежащих модулям TPM всех ПК на предприятии, или контроллер фабрики центра обработки данных может иметь базу данных модулей TPM на всех блейд-серверах. В Windows вы можете использовать провайдер NCrypt, описанный в разделе «Поставщик шифрования платформы в Windows 8», чтобы прочитать общедоступную часть EK.
Где-то внутри TPM находится закрытый ключ RSA. Этот ключ заперт там - его никогда не увидит внешний мир. Я хочу, чтобы TPM что-то подписывал своим закрытым ключом (т. Е. Зашифровывал это своим закрытым ключом).
Поэтому мне нужна самая простая операция, которая может существовать:
Зашифруйте что-нибудь своим закрытым ключом. Я даже (пока) не прошу более сложных вещей:
- «запечатывать» его по состоянию ПЦР
- создание ключа и сохранение его в энергозависимой или энергонезависимой памяти
- создание симметричного ключа и попытка загрузить его в TPM
Я прошу выполнить самую простую операцию, которую может выполнять TPM. Почему невозможно получить информацию о том, как это сделать?
Я могу получить случайные данные
Полагаю, я был бойким, когда сказал, что подписание RSA - это самое простое, что может сделать TPM. Самое основное , что доверенный платформенный модуль может быть предложено сделать , это дать мне случайные байты. Это я понял, как это сделать:
public Byte[] GetRandomBytesTPM(int desiredBytes)
{
//The maximum random number size is limited to 4,096 bytes per call
Byte[] result = new Byte[desiredBytes];
BCRYPT_ALG_HANDLE hAlgorithm;
BCryptOpenAlgorithmProvider(
out hAlgorithm,
BCRYPT_RNG_ALGORITHM, //AlgorithmID: "RNG"
MS_PLATFORM_CRYPTO_PROVIDER, //Implementation: "Microsoft Platform Crypto Provider" i.e. the TPM
0 //Flags
);
try
{
BCryptGenRandom(hAlgorithm, @result[0], desiredBytes, 0);
}
finally
{
BCryptCloseAlgorithmProvider(hAlgorithm);
}
return result;
}
Необычная вещь
Я понимаю, что количество людей, использующих TPM, очень мало. Вот почему ни у кого в Stackoverflow нет ответа. Так что я не могу стать слишком жадным в поисках решения моей общей проблемы. Но что бы я действительно хочу сделать , это «уплотнение» некоторые данные:
- представить TPM некоторые данные (например, 32 байта ключевого материала)
- заставить TPM зашифровать данные, возвращая некоторую непрозрачную структуру больших двоичных объектов
- позже попросите TPM расшифровать blob
- дешифрование будет работать только в том случае, если регистры PCR TPM такие же, как и во время шифрования.
Другими словами:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Cryptography Next Gen (Cng, aka BCrypt) поддерживает TPM
Первоначальный API криптографии в Windows назывался Crypto API.
Начиная с Windows Vista, Crypto API был заменен на Cryptography API: Next Generation (внутреннее название BestCrypt , сокращенно BCrypt , не путать с алгоритмом хеширования паролей ).
Windows поставляется с двумя поставщиками BCrypt :
- Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) по умолчанию : программная реализация всех примитивов по умолчанию (хеширование, симметричное шифрование, цифровые подписи и т. Д.) - Поставщик шифрования платформы Microsoft (
MS_PLATFORM_CRYPTO_PROVIDER
): поставщик, предоставляющий доступ к TPM.
Platform Crypto провайдер не документирован на MSDN, но есть документы с сайта 2012 Microsoft Research:
Набор средств криптографического провайдера платформы TPM
Поставщик криптографии платформы TPM и набор инструментов содержит образец кода, служебные программы и документацию для использования функций, связанных с TPM, в Windows 8. Описанные подсистемы включают поставщика криптографии платформы Crypto-Next-Gen (CNG) на основе TPM и способы предоставления услуг аттестации. могут использовать новые функции Windows. Поддерживаются системы на базе TPM1.2 и TPM2.0.
Создается впечатление , что цель Microsoft заключается в поверхность ТРМ функциональность криптографической с Microsoft Platform Crypto Provider в Cryptography NG API.
Шифрование с открытым ключом с использованием Microsoft BCrypt
При условии:
- я хочу выполнить асимметричное шифрование RSA (с использованием TPM)
- Microsoft BestCrypt поддерживает асимметричное шифрование RSA
- Microsoft BestCrypt имеет поставщика TPM
путь вперед может заключаться в том, чтобы выяснить, как выполнять цифровую подпись с помощью Microsoft Cryptography Next Gen API .
Следующим моим шагом будет создание кода для шифрования в BCrypt с открытым ключом RSA с использованием стандартного provider ( MS_PRIMITIVE_PROVIDER
). Например:
modulus
: 0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55publicExponent
: 65537
С этим кодом я могу переключиться на использование TPM Provider ( MS_PLATFORM_CRYPTO_PROVIDER
).
22.02.2016: И поскольку Apple вынуждена помогать в расшифровке пользовательских данных, возобновился интерес к тому, как заставить TPM выполнять самую простую задачу, для которой он был изобретен, - шифрование чего-либо.
Это примерно равносильно тому, что у каждого есть машина, но никто не знает, как ее завести. Он может делать действительно полезные и крутые вещи, если только мы сможем пройти шаг 1 .