Как я могу шифровать байты с помощью модуля TPM машины?
CryptProtectDatah1 >
Windows предоставляет (относительно) простой API для шифрования blob с помощью API CryptProtectData
, который мы можем обернуть простой в использовании функцией:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Детали ProtectBytes
менее важны, чем идея, что вы можете использовать ее довольно легко:
- Вот байты, которые я хочу зашифровать секретным ключом, хранящимся в
System
- верните зашифрованный blob
Возвращаемое blob - это недокументированная структура documentation, которая содержит все необходимое для дешифрования и возврата исходных данных ( хэш-алгоритм, алгоритм шифрования, соль, подпись 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 what the SDK says.
}
Как сделать то же самое с TPM?
Приведенный выше код полезен для шифрования данных только для локальной машины. Данные зашифрованы с использованием учетной записи System
в качестве генератора ключей (детали, в то время как интересные, несущественны). Конечным результатом является то, что я могу шифровать данные (например, главный ключ шифрования жесткого диска), который может быть дешифрован только локальным компьютером.
Теперь пришло время сделать еще один шаг. Я хочу зашифровать некоторые данные (например, главный ключ шифрования жесткого диска), который может быть расшифрован только локальным TPM. Другими словами, я хочу заменить рабочую среду Qualcomm Trusted Execution Environment (TEE) на блок-диаграмме ниже для Android, с TPM в Окна:
Примечание. Я понимаю, что TPM не выполняет подписи данных (или если это так, это не гарантирует, что подписи одних и тех же данных будут давать один и тот же двоичный вывод каждый раз). Именно поэтому я готов заменить "RSA-подпись" на "шифрование 256-битного blob с помощью связанного с аппаратным обеспечением ключа".
Итак, где код?
Проблема в том, что программирование TPM полностью недокументировано в MSDN. Для выполнения каких-либо операций API недоступен. Вместо этого вам нужно найти копию Trusted Computing Group Software Stack (aka 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, вы не можете использовать его из С#. Для этого требуется:
- OpenSSL
- PTHREAD
Я просто хочу, чтобы код шифровал что-то с моим TPM.
Приведенный выше CryptProtectData
не требует ничего, кроме того, что в теле функции.
Что такое эквивалентный код для шифрования данных с помощью TPM? Как отмечали другие, вам, вероятно, придется проконсультироваться с тремя руководствами TPM и самостоятельно построить blobs. Вероятно, это связано с командой 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 - спецификация версии 1.2, упоминается привязка:
10.3 TPM_UnBind
TPM_UnBind принимает данные blob, которые являются результатом команды Tspi_Data_Bind и расшифровывает ее для экспорта в Пользователь. Вызывающий должен разрешить использование ключа, который расшифрует входящий блок. TPM_UnBind работает поэтапно и не имеет понятия о каком-либо отношении между одним блоком и другим.
Что сбивает с толку команда no Tspi_Data_Bind
.
Исследование усилий
Это ужасает то, как никто никогда не удосужился документировать TPM или его работу. Как будто они все время придумывали эту классную игру, но не хотели иметь дело с болезненным шагом, чтобы сделать ее пригодной для использования.
Начиная с бесплатной книги Практическое руководство по TPM 2.0: использование надежного модуля платформы в новый век безопасности:
Глава 3 - Краткое руководство по TPM 2.0
TPM имеет доступ к самогенерированному закрытому ключу, поэтому он может шифровать ключи с помощью открытого ключа, а затем сохранять полученный в результате капли на жестком диске. Таким образом, TPM может хранить практически неограниченное количество ключей, доступных для использования, но не тратить драгоценное внутреннее хранилище. Ключи, хранящиеся на жестком диске, могут быть удалены, но они также могут быть скопированы, что казалось дизайнерам как приемлемый компромисс.
Как я могу зашифровать ключ открытым ключом TPM?
Глава 4 - Существующие приложения, использующие TPM
Приложения, которые должны использовать TPM, но Dont
В последние несколько лет число веб-приложений увеличилось. Среди них сетевое резервное копирование и хранение. В настоящее время большое количество компаний предлагают такие услуги, но, насколько нам известно, ни один из клиентов этих служб не позволяет пользователю блокировать ключ для службы резервного копирования для TPM. Если бы это было сделано, было бы неплохо, если бы сам ключ TPM был подкреплен дублированием его на нескольких машинах. Это, по-видимому, возможность для разработчиков.
Как разработчик блокирует ключ для TPM?
Глава 9 - Heirarchies
ИСПОЛЬЗУЙТЕ СЛУЧАЙ: ХРАНЕНИЕ ПАРОЛЬ ВХОДА
В типичном файле паролей хранятся соленые хэши паролей. Проверка состоит из соления и хэширования поставляемого пароля и сравнения его с сохраненным значением. Потому что вычисление не включает в себя секрет, его субъект в оффлайновой атаке на файл паролей.
В этом случае используется ключ HMAC сгенерированный TPM. В файле паролей хранится HMAC соленого пароля. Проверка состоит из соления и HMACing предоставленного пароля и сравнения его с сохраненным значением. Поскольку автономный злоумышленник не имеет ключа HMAC, злоумышленник не может установить атаку, выполнив вычисление.
Это может сработать. Если у TPM есть секретный ключ HMAC, и только мой TPM знает ключ HMAC, тогда я мог бы заменить "Sign (aka TPM encrypt with private key)" с "HMAC". Но затем на самой следующей строке он полностью вспять:
TPM2_Create, указав ключ HMAC
Это не секрет TPM, если мне нужно указать ключ HMAC. Тот факт, что ключ HMAC не является секретным, имеет смысл, когда вы понимаете, что это глава о криптографических утилитах, предоставляемых TPM. Вместо того, чтобы вам самому писать SHA2, AES, HMAC или RSA, вы можете повторно использовать то, что уже укомплектовано TPM.
Глава 10 - Клавиши
В качестве защитного устройства способность приложения использовать ключи при сохранении их безопасности на аппаратном устройстве является максимальной силой TPM. TPM может генерировать и импортировать ключи, созданные извне. Он поддерживает как асимметричные, так и симметричные клавиши.
Отлично! Как вы это делаете?
Генератор ключей
Возможно, наибольшей силой TPM является его способность генерировать криптографический ключ и защищать его секрет в пределах аппаратной границы. Генератор ключей основан на собственном генераторе случайных чисел TPM и не полагается на внешние источники случайности. Таким образом, это устраняет недостатки, основанные на слабом программном обеспечении с недостаточным источником энтропии.
Имеет ли TPM возможность генерировать криптографические ключи и защищать свои секреты на границе аппаратного обеспечения? Так, как?
Глава 12 - Регистры конфигурации платформы
ПЦР для авторизации
ИСПОЛЬЗУЙТЕ СЛУЧАЙ: УПЛОТНЕНИЕ ТИПОВОГО КОДА КОДИРОВАНИЯ ДИСКА К СОСТОЯНИЮ ПЛАТФОРМЫ
Приложения шифрования с полным диском гораздо более безопасны, если TPM защищает ключ шифрования, чем если он хранится на том же диске, защищенном только паролем. Во-первых, аппаратное обеспечение TPM имеет защиту от забивания (см. Главу 8 для подробного описания защиты от атаки с помощью словаря TPM), что делает грубую атаку на пароль нецелесообразной. Ключ, защищенный только программным обеспечением, гораздо более уязвим для слабого пароля. Во-вторых, программный ключ, хранящийся на диске, намного легче украсть. Возьмите диск (или резервную копию диска), и вы получите ключ. Когда TPM удерживает ключ, вся платформа или, по крайней мере, диск и материнская плата должны быть украдены.
Уплотнение позволяет защищать ключ не только паролем, но и политикой. Типичная политика блокирует ключ к значениям ПЦР (состояние программного обеспечения) в момент герметизации. Это предполагает, что состояние с первой загрузкой не скомпрометировано. Любое предустановленное вредоносное ПО, присутствующее при первой загрузке, будет измерено в ПЦР, и, таким образом, ключ будет запечатан в скомпрометированном состоянии программного обеспечения. Менее доверяющее предприятие может иметь стандартный образ диска и печать для ПЦР, представляющих это изображение. Эти значения ПЦР будут предварительно рассчитаны на предположительно более надежной платформе. Еще более сложное предприятие будет использовать TPM2_PolicyAuthorize и предоставить несколько билетов, разрешающих набор доверенных значений ПЦР. Подробное описание авторизации политики и ее приложения см. В главе 14. Для решения проблемы PCRbritleness.
Хотя пароль также может защитить ключ, есть усиление безопасности даже без пароля ключа TPM. Злоумышленник может загружать платформу без предоставления пароля TPMkey, но не смог войти в систему без имени пользователя и пароля ОС. OSsecurity защищает данные. Злоумышленник может загрузить альтернативную ОС, скажем, с живого DVD или USB-накопителя, а не с жесткого диска, чтобы обойти защиту входа в ОС. Однако эта другая конфигурация загрузки и программное обеспечение изменили бы значения PCR. Поскольку эти новые ПЦР не совпадают с запечатанными значениями, TPM не будет выпускать ключ дешифрования, а жесткий диск не может быть расшифрован.
Отлично! Это именно тот случай, который мне нужен. Это также прецедент, используемый Microsoft для TPM. Как это сделать??
Итак, я прочитал эту целую книгу, и она ничего не принесла. Это довольно впечатляет, потому что это 375 страниц. Вы задаетесь вопросом, что в книге содержится - и оглядываясь назад, я понятия не имею.
Итак, мы отказываемся от окончательного руководства по программированию TPM и вместо этого обращаемся к документации Microsoft:
Из Инструментарий Crypto-Provider для платформы TPM для платформы TPM. В нем точно указано, что я хочу делать:
Ключ одобрения или EK
EK предназначен для обеспечения надежного криптографического идентификатора для платформы. Предприятие может поддерживать базу данных ключей одобрения, принадлежащих TPM всех ПК на своем предприятии, или контроллер материнской платы центра обработки данных может иметь базу данных TPM во всех blade-серверах. В Windows вы можете использовать поставщика NCrypt, описанный в разделе "Platform Crypto Provider в Windows 8", чтобы прочитать общедоступную часть EK.
Где-то внутри TPM находится закрытый ключ RSA. Этот ключ заперт там - никогда не увидишь внешний мир. Я хочу, чтобы TPM что-то подписывал с помощью закрытого ключа (т.е. Шифровал его с помощью закрытого ключа).
Итак, я хочу, чтобы существовала самая основная операция:
Зашифруйте что-нибудь своим личным ключом. Я даже не просил более сложных вещей:
- "запечатывание" его на основе состояния ПЦР
- создание ключа и сохранение его в энергозависимой или энергонезависимой памяти
- создание симметричного ключа и его загрузка в TPM
Я прошу самую основную операцию, которую может сделать TPM. Почему невозможно получить какую-либо информацию о том, как это сделать?
Я могу получить случайные данные
Я полагаю, что я был ослеп, когда я сказал, что подписка RSA является самой простой вещью, которую может сделать TPM. наиболее, которую может попросить 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 шифровал данные, возвращая некоторую непрозрачную структуру blob
- попросите TPM расшифровать blob
- дешифрование будет работать только в том случае, если регистры TPM PCR такие же, как и во время шифрования.
Другими словами:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Криптография Next Gen (Cng, aka BCrypt) поддерживает TPM
Оригинальный API криптографии в Windows был известен как Crypto API.
Начиная с Windows Vista, Crypto API был заменен на API криптографии: следующее поколение (внутренне известный как BestCrypt, сокращенно BCrypt, не следует путать с алгоритмом хэширования пароля).
Windows поставляется с двумя провайдерами BCrypt:
- Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) по умолчанию: стандартная программная реализация всех примитивов (хеширование, симметричное шифрование, цифровые подписи и т.д.) - Поставщик Crypto для платформы Microsoft (
MS_PLATFORM_CRYPTO_PROVIDER
): поставщик, предоставляющий доступ к TPM.
Поставщик платформы Crypto не зарегистрирован в MSDN, но имеет документацию с сайта Microsoft Research 2012:
Инструментарий Crypto-Provider платформы TPM
Провайдер и инструментарий платформы TPM Platform содержат пример кода, утилиты и документацию для использования функциональных возможностей, связанных с TPM, в Windows 8. В описываемых подсистемах используется крипто-провайдер платформы Crypto-Next-Gen (CNG), поддерживаемый TPM, и как аттестация -сервисные провайдеры могут использовать новые функции Windows. Поддерживаются системы на основе TPM1.2 и TPM2.0.
Похоже, что намерение Microsoft состоит в том, чтобы покрыть криптографические функции TPM с помощью Microsoft Crypto Provider API Cryptography NG.
Шифрование с открытым ключом с использованием Microsoft BCrypt
Учитывая, что:
- Я хочу выполнить асимметричное шифрование RSA (используя TPM)
- Microsoft BestCrypt поддерживает асимметричное шифрование RSA
- Microsoft BestCrypt имеет поставщика TPM
В будущем может возникнуть вопрос о том, как сделать цифровое подписание с помощью Microsoft Cryptography Next Gen API.
Следующим шагом будет создание кода для шифрования в BCrypt с открытым ключом RSA с использованием стандартного поставщика (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 55 -
publicExponent
: 65537
С помощью этого кода я могу переключиться на использование поставщика TPM (MS_PLATFORM_CRYPTO_PROVIDER
).
2/22/2016: И когда Apple вынуждена помогать расшифровывать пользовательские данные, возникает повышенный интерес к тому, как заставить TPM выполнить самую простую задачу, для которой он был изобретен для - шифрования чего-то.
Это примерно эквивалентно каждому, кто владеет автомобилем, но никто не знает, как его запустить. Он может делать действительно полезные и интересные вещи, если только мы могли бы пройти мимо Шаг 1.