マシンのTPMモジュールを使用してバイトを暗号化するにはどうすればよいですか?
CryptProtectData
Windowsは、APIを使用してblobを暗号化する(比較的)単純なAPIを提供しCryptProtectData
ます。これを使いやすい関数をラップできます。
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
の詳細は、ProtectBytes
非常に簡単に使用できるという考えほど重要ではありません。
- ここに私が保持している秘密鍵で暗号化したいバイトがあります
System
- 暗号化されたblobを返してください
返されるblobは、ドキュメント化されていないドキュメント構造であり、元のデータ(ハッシュアルゴリズム、暗号化アルゴリズム、salt、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でのみ復号化できる一部のデータ(ハードドライブ暗号化マスターキーなど)を暗号化したい。つまり、以下のAndroidのブロック図にあるQualcomm Trusted Execution Environment(TEE)をWindowsのTPMに置き換えます。
注:TPMはデータ署名を行わないことを理解しています(または、署名しても、同じデータに署名しても毎回同じバイナリ出力が得られるとは限りません)。これが、「RSA署名」を「ハードウェアにバインドされたキーで256ビットのblobを暗号化する」に置き換えたいという理由です。
それで、コードはどこにありますか?
問題は、TPMプログラミングがMSDNで完全に文書化されていないことです。操作を実行するために使用できるAPIはありません。代わりに、Trusted Computing Groupのソフトウェアスタック(別名TSS)のコピーを見つけ、TPMに送信するコマンドをペイロードとともに、どのような順序で見つけ、ウィンドウの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 I / Oコマンドを発行してテキストファイルを作成しようとすることと同じです。
なぜズボンを使用しないのですか
Trusted Computing Group(TCG)は独自のAPI、TCB Software Stack(TSS)を定義しました。このAPIの実装は一部の人々によって作成され、TrouSerSと呼ばれています。次に、そのプロジェクトをWindowsに移植しました。
そのコードの問題は、Windowsの世界に移植できないことです。たとえば、Delphiからは使用できません。C#からは使用できません。以下が必要です。
- OpenSSL
- pThread
TPMでコードを暗号化したいだけです。
上記CryptProtectData
は、関数本体にあるもの以外何も必要としません。
TPMを使用してデータを暗号化するための同等のコードは何ですか?他の人が指摘したように、おそらく3つのTPMマニュアルを参照して、自分でblobを構築する必要があります。おそらくTPM_seal
コマンドが関係しています。データを封印したくないと思いますが、バインドしたいと思います。
バインド – TPMバインドキーを使用してデータを暗号化します。TPMバインドキーは、ストレージキーから派生した一意のRSAキーです。 封印 –結合と同様の方法でデータを暗号化しますが、さらに、データを復号化(封印解除)するためにTPMが必要な状態を指定します
必要な20行のコードを見つけるために、必要な3つのボリュームを読みます。
しかし、私は何を読んでいるのか分かりません。チュートリアルや例があったら、私が試してみるかもしれません。しかし、私は完全に迷っています。
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メイン-パート3コマンド-仕様バージョン1.2を見ると、bindに関する記述があります。
10.3 TPM_UnBind
TPM_UnBindは、Tspi_Data_Bindコマンドの結果であるデータBLOBを受け取り、それを復号化してユーザーにエクスポートします。呼び出し元は、着信BLOBを復号化するキーの使用を承認する必要があります。TPM_UnBindはブロックごとに動作し、ブロック間の関係についての概念はありません。
混乱しているのは、Tspi_Data_Bind
コマンドがないことです。
研究努力
TPMやその操作を文書化するために誰もこれまで悩まなかったことは恐ろしいことです。まるで、このクールなものを思いつくためにすべての時間を費やしているかのようですが、何かに使用できるようにするための苦痛なステップに対処したくありませんでした。
(現在)無料の本「TPM 2.0の実用ガイド:セキュリティの新時代におけるトラステッドプラットフォームモジュールの使用」から始めます。
第3章-TPM 2.0のクイックチュートリアル
TPMは自己生成された秘密キーにアクセスできるため、公開キーでキーを暗号化し、結果のblobをハードディスクに保存できます。このようにして、TPMは実質的に無制限の数のキーを使用可能に保つことができますが、貴重な内部ストレージを無駄にすることはありません。ハードディスクに保存されたキーは消去できますが、バックアップすることもできます。これは、設計者には許容できるトレードオフのように見えました。
TPMの公開キーを使用してキーを暗号化するにはどうすればよいですか?
第4章-TPMを使用する既存のアプリケーション
TPMを使用する必要があるが使用しないアプリケーション
過去数年間で、Webベースのアプリケーションの数は増加しています。その中には、Webベースのバックアップとストレージがあります。現在、多くの企業がそのようなサービスを提供していますが、私たちが知る限り、これらのサービスのクライアントのいずれも、ユーザーがバックアップサービスのキーをTPMにロックすることを許可していません。これが行われた場合、TPMキー自体が複数のマシンで複製されてバックアップされていれば、確かに良いことです。これは、開発者にとっての機会のようです。
開発者はどのようにしてTPMのキーをロックしますか?
第9章-階層
使用例:ログインパスワードの保存
典型的なパスワードファイルは、パスワードのソルトハッシュを格納します。検証は、提供されたパスワードをソルトおよびハッシュし、それを格納された値と比較することで構成されます。計算には秘密が含まれていないため、パスワードファイルに対するオフライン攻撃の対象になります。
この使用例では、TPMで生成されたHMACキーを使用します。パスワードファイルには、ソルトパスワードのHMACが格納されます。検証は、提供されたパスワードをソルト処理およびHMAC処理し、それを格納された値と比較することで構成されます。オフラインの攻撃者はHMACキーを持っていないため、攻撃者は計算を実行して攻撃を仕掛けることはできません。
これはうまくいくかもしれません。TPMに秘密のHMACキーがあり、自分のTPMだけがHMACキーを知っている場合は、「署名(別名TPMはその秘密キーで暗号化)」を「HMAC」に置き換えることができます。しかし、次の行で完全に逆転します。
TMAC2_Create、HMACキーを指定
HMACキーを指定する必要がある場合、それはTPMシークレットではありません。HMACキーが秘密ではないという事実は、これがTPMが提供する暗号化ユーティリティについての章であることを理解した場合に理にかなっています。SHA2、AES、HMAC、またはRSAを自分で記述する必要はなく、TPMがすでに備えているものを再利用できます。
第10章-キー
セキュリティデバイスとして、ハードウェアデバイスでキーを安全に保ちながらキーを使用するアプリケーションの機能は、TPMの最大の強みです。TPMは、外部で生成されたキーを生成およびインポートできます。非対称キーと対称キーの両方をサポートしています。
優れた!どうやってやるの!?
キージェネレーター
間違いなく、TPMの最大の強みは、暗号化キーを生成し、ハードウェア境界内でその秘密を保護する能力です。キージェネレーターは、TPM独自の乱数ジェネレーターに基づいており、外部の乱数発生源に依存しません。したがって、エントロピーのソースが不十分な弱いソフトウェアソフトウェアに基づく弱点を排除します。
ん TPMは、暗号鍵を生成し、ハードウェアの境界内にその秘密を保護する能力を持っていますか?そうですか?
第12章-プラットフォーム構成レジスタ
認可のためのPCR
ユースケース:ハードディスク暗号化キーをプラットフォーム状態にシールする
フルディスク暗号化アプリケーションは、TPMが暗号化キーを保護する場合、同じディスクに保存され、パスワードのみで保護される場合よりもはるかに安全です。第1に、TPMハードウェアにはアンチハンマリング保護機能(TPM辞書攻撃保護の詳細については第8章を参照)があり、パスワードへのブルートフォース攻撃が実用的ではありません。ソフトウェアのみで保護されたキーは、弱いパスワードに対してはるかに脆弱です。第二に、ディスクに保存されているソフトウェアキーは盗むのがはるかに簡単です。ディスク(またはディスクのバックアップ)を取得すると、キーが取得されます。TPMがキーを保持している場合、プラットフォーム全体、または少なくともディスクとマザーボードを盗む必要があります。
シーリングでは、パスワードだけでなくポリシーによってもキーを保護できます。一般的なポリシーでは、封印時にPCR値(ソフトウェアの状態)の現在のキーをロックします。これは、最初の起動時の状態が損なわれていないことを前提としています。最初の起動時に存在するプレインストールされたマルウェアはすべてPCRに測定され、したがって、キーは侵害されたソフトウェア状態に封印されます。信頼性の低い企業には、標準のディスクイメージがあり、そのイメージを表すPCRをシールする場合があります。これらのPCR値は、おそらくより信頼できるプラットフォームで事前計算されます。さらに洗練された企業はTPM2_PolicyAuthorizeを使用し、信頼されたPCR値のセットを承認するいくつかのチケットを提供します。ポリシーの承認とPCRの脆弱性の問題を解決するためのそのアプリケーションの詳細については、第14章を参照してください。
パスワードでキーを保護することもできますが、TPMキーパスワードがなくてもセキュリティは向上します。攻撃者はTPMkeyパスワードを提供せずにプラットフォームを起動できますが、OSユーザー名とパスワードなしではログインできません。OSsecurityはデータを保護します。攻撃者は、OSのログインセキュリティをバイパスするために、ハードドライブからではなく、ライブDVDまたはUSBスティックなどから代替OSを起動する可能性があります。ただし、この異なるブート構成とソフトウェアはPCR値を変更します。これらの新しいPCRは封印された値と一致しないため、TPMは復号化キーを解放せず、ハードドライブを復号化できませんでした。
優れた!これはまさに私が望んでいるユースケースです。これは、MicrosoftがTPMを使用するユースケースでもあります。どうすればいいのですか!?
それで、私はその本全体を読みました、そしてそれは何の役にも立ちませんでした。それは375ページなので、これは非常に印象的です。あなたはその本が何を含んでいたのだろうと思います-そしてそれを振り返って、私にはわかりません。
そのため、TPMのプログラミングに関する決定的なガイドをあきらめ、代わりにMicrosoftのドキュメントを参照します。
マイクロソフトTPMプラットフォーム暗号-プロバイダーツールキット。それは私がしたいことを正確に述べています:
保証キーまたはEK
EKは、プラットフォームに信頼できる暗号識別子を提供するように設計されています。企業は、企業内のすべてのPCのTPMに属する保証キーのデータベースを維持している場合もあれば、データセンターファブリックコントローラーがすべてのブレードのTPMのデータベースを持っている場合もあります。Windowsでは、「Windows 8のプラットフォーム暗号プロバイダー」セクションで説明されているNCryptプロバイダーを使用して、EKのパブリック部分を読み取ることができます。
TPMのどこかにRSA秘密鍵があります。その鍵はそこに閉じ込められています-外の世界からは決して見えません。TPMに秘密キーで何かに署名してほしい(つまり、秘密キーで暗号化する)。
だから私はおそらく存在することができる最も基本的な操作が欲しい:
秘密鍵で何かを暗号化します。私は(まだ)より複雑なものを求めているわけではありません。
- PCRの状態に基づいて「封印」する
- キーを作成し、それを揮発性または不揮発性メモリに保存する
- 対称キーを作成して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、別名BCrypt)がTPMをサポート
Windowsの元の暗号化APIは、暗号APIとして知られていました。
Windows Vistaでは以降では、暗号化APIはに置き換えられている暗号化API:次世代(内部的として知られているBestCryptのと略記、bcryptのは、と混同しないようにパスワードのハッシュアルゴリズム)。
Windowsには2つのBCrypt プロバイダーが付属しています。
- Microsoft Primitive Provider(
MS_PRIMITIVE_PROVIDER
)default:すべてのプリミティブのデフォルトソフトウェア実装(ハッシュ、対称暗号化、デジタル署名など) - Microsoft Platform Crypto Provider(
MS_PLATFORM_CRYPTO_PROVIDER
):TPMアクセスを提供するプロバイダー
プラットフォーム暗号のプロバイダは、MSDNで文書化されていませんが、2012マイクロソフトリサーチサイトからドキュメントを持っています:
TPMプラットフォーム暗号プロバイダーツールキット
TPMプラットフォーム暗号化プロバイダーおよびツールキットには、Windows 8でTPM関連の機能を使用するためのサンプルコード、ユーティリティ、およびドキュメントが含まれています。 Windowsの新機能を使用できます。TPM1.2およびTPM2.0ベースのシステムの両方がサポートされています。
Microsoftの意図は、暗号化NG APIのMicrosoft Platform Crypto ProviderでTPM暗号機能を表面化することです。
Microsoft BCryptを使用した公開鍵暗号化
とすれば:
- RSA非対称暗号化を実行したい(TPMを使用)
- Microsoft BestCryptはRSA非対称暗号化をサポートします
- Microsoft BestCryptにはTPMプロバイダーがあります
今後の方法は、Microsoft Cryptography Next Gen APIを使用してデジタル署名を行う方法を理解することです。
次のステップは、RSA公開鍵を使用して、BCryptで暗号化を行うためのコードを、標準プロバイダーを使用して作成することです(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プロバイダーの使用に切り替えることができる場合があります(MS_PLATFORM_CRYPTO_PROVIDER
)。
2016年2月22日:Appleがユーザーデータの復号化を強制されるようになったことで、TPMが発明した最も単純なタスク、つまり何かを暗号化することをTPMに実行させる方法に新たな関心が集まっています。
これは、車を所有するすべての人とほぼ同じですが、車の始動方法は誰にもわかりません。ステップ1を通過できさえすれば、本当に便利でクールなことができます。