TPM (Güvenilir Platform Modülü) kullanılarak baytlar nasıl şifrelenir


110

Bir makinenin TPM modülünü kullanarak baytları nasıl şifreleyebilirim?

CryptProtectData

Windows, API'yi kullanarak bir blob'u şifrelemek için (nispeten) basit bir CryptProtectDataAPI sağlar; bu, kullanımı kolay bir işlevi sarabilir:

public Byte[] ProtectBytes(Byte[] plaintext)
{
   //...
}

Detayları, ProtectBytesonu oldukça kolay kullanabileceğiniz fikrinden daha az önemlidir:

  • burada tutulan gizli bir anahtarla şifrelenmesini istediğim baytlar System
  • bana şifreli blobu geri ver

Döndürülen blob , orijinal verilerin (karma algoritma, şifre algoritması, tuz, HMAC imzası, vb.) Şifresini çözmek ve döndürmek için gereken her şeyi içeren belgelenmemiş bir belge yapısıdır.

Tamlık ProtectBytesiçin, Crypt APIbaytları korumak için kullanan örnek sözde kod uygulaması burada :

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 ile aynı şey nasıl yapılır?

Yukarıdaki kod, yalnızca yerel makinenin verilerini şifrelemek için kullanışlıdır. Veriler, Systemanahtar oluşturucu olarak hesap kullanılarak şifrelenir ( ilginç olsa da ayrıntılar önemsizdir ). Sonuç olarak, yalnızca yerel makine tarafından şifresi çözülebilen verileri (örneğin bir sabit sürücü şifreleme ana anahtarı) şifreleyebilirim.

Şimdi bunu bir adım daha ileri götürme zamanı. Yalnızca yerel TPM tarafından şifresi çözülebilen bazı verileri (örneğin, sabit sürücü şifreleme ana anahtarı) şifrelemek istiyorum. Başka bir deyişle, Android için aşağıdaki blok şemasında Qualcomm Trusted Execution Environment'ı ( TEE ) Windows'taki TPM ile değiştirmek istiyorum :

görüntü açıklamasını buraya girin

Not : TPM'nin veri imzalama yapmadığının farkındayım (veya yaparsa, aynı verilerin imzalanmasının her seferinde aynı ikili çıktıyı vereceğini garanti etmez). Bu nedenle, "RSA imzalamayı" , "256 bitlik bir blob'u donanıma bağlı bir anahtarla şifrelemek " ile değiştirmeye istekli olacağım .

Peki kod nerede?

Sorun, TPM programlamasının MSDN'de tamamen belgelenmemiş olmasıdır . Herhangi bir işlemi gerçekleştirmek için kullanılabilir API yoktur. Bunun yerine, Trusted Computing Group'un Yazılım Yığınının (TSS olarak da bilinir) bir kopyasını bulmanız , TPM'ye hangi sırayla yüklerle birlikte hangi komutların gönderileceğini bulmanız ve komutları doğrudan göndermek için Window'un Tbsip_Submit_Command işlevini çağırmanız gerekir :

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, eylemleri gerçekleştirmek için daha yüksek düzeyde API'ye sahip değildir.

Bu, sabit sürücünüze SATA I / O komutları göndererek bir metin dosyası oluşturmaya çalışmanın ahlaki karşılığıdır .

Neden sadece Pantolon kullanmıyorsunuz?

Trusted Computing Group (TCG) kendi API'sini tanımladı: TCB Yazılım Yığını (TSS) . Bu API'nin bir uygulaması bazı kişiler tarafından oluşturulmuştur ve TrouSerS olarak adlandırılır . Bir adam daha sonra bu projeyi Windows'a taşıdı .

Bu kodla ilgili sorun, Windows dünyasına taşınabilir olmamasıdır. Örneğin, Delphi'den kullanamazsınız, C # üzerinden kullanamazsınız. Gerektirir:

  • OpenSSL
  • pThread

Kodun TPM'mle bir şeyi şifrelemesini istiyorum .

Yukarıdakiler CryptProtectData, işlev gövdesinde olandan başka bir şey gerektirmez.

TPM kullanarak verileri şifrelemek için eşdeğer kod nedir? Diğerlerinin de belirttiği gibi, muhtemelen üç TPM kılavuzuna başvurmanız ve blobları kendiniz oluşturmanız gerekir . Muhtemelen TPM_sealkomutu içeriyor . Verileri mühürlemek istemediğimi düşünmeme rağmen , onu bağlamak istediğimi düşünüyorum :

Bağlama - bir depolama anahtarından türetilmiş benzersiz bir RSA anahtarı olan TPM bağlama anahtarını kullanarak verileri şifreler. Mühürleme - verileri, bağlanmaya benzer şekilde şifreler, ancak buna ek olarak, verilerin şifresinin çözülmesi (mühürlenmemiş) için TPM'nin olması gereken bir durumu belirtir

İhtiyacım olan 20 kod satırını bulmak için gerekli üç cildi okumaya çalışıyorum:

Ama ne okuduğuma dair hiçbir fikrim yok . Herhangi bir öğretici veya örnek olsaydı, bir şansım olabilirdi. Ama tamamen kayboldum.

Bu yüzden Stackoverflow'a soruyoruz

Aynı şekilde şunları sağlayabildim:

Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
   //...
   CryptProtectData(...); 
   //...
}

birisi karşılık gelen eşdeğeri sağlayabilir:

Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
   //...
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   //...snip...
   Tbsip_Submit_Command(...);
   //...
}

Bu, SystemLSA'da kilitli bir anahtarın TPM'de kilitli olması dışında aynı şeyi yapar ?

Araştırma Başlangıcı

Tam olarak ne olduğunu bilmiyorum bağlayan araçlar. Ama TPM Main bakarak - Bölüm 3 Komutları - Şartname Sürüm 1.2, bir söz olduğunu bağlama :

10.3 TPM_UnBind

TPM_UnBind, bir Tspi_Data_Bind komutunun sonucu olan veri blobunu alır ve Kullanıcıya dışa aktarmak için şifresini çözer. Arayan, gelen blobun şifresini çözecek anahtarın kullanımına yetki vermelidir. TPM_UnBind, blok-blok esasına göre çalışır ve bir blok ile diğeri arasında herhangi bir ilişki kavramı yoktur.

Kafa karıştıran şey ,Tspi_Data_Bind komut olmaması .

Araştırma Çabası

Hiç kimsenin TPM'yi veya işleyişini belgeleme zahmetine girmemiş olması dehşet verici. Sanki tüm zamanlarını oynamak için bu harika şeyi bulmaya harcadılar , ancak onu bir şey için kullanılabilir hale getirmenin acı verici adımıyla uğraşmak istemediler .

(Şimdi) ücretsiz kitaptan başlayarak TPM 2.0 için Pratik Bir Kılavuz: Yeni Güvenlik Çağında Güvenilir Platform Modülünü Kullanma :

Bölüm 3 - TPM 2.0 Hakkında Hızlı Eğitim

TPM'nin kendi oluşturduğu bir özel anahtara erişimi vardır, böylece anahtarları bir ortak anahtarla şifreleyebilir ve ardından oluşan blob'u sabit diskte depolayabilir. Bu şekilde, TPM neredeyse sınırsız sayıda anahtarı kullanılabilir durumda tutabilir ancak değerli dahili depolamayı boşa harcamaz. Sabit diskte depolanan anahtarlar silinebilir, ancak aynı zamanda yedeklenebilirler, bu da tasarımcılara kabul edilebilir bir değiş tokuş gibi göründü.

TPM'nin genel anahtarıyla bir anahtarı nasıl şifreleyebilirim?

Bölüm 4 - TPM Kullanan Mevcut Uygulamalar

TPM Kullanması Gereken Ancak Kullanmaması Gereken Uygulamalar

Geçtiğimiz birkaç yılda web tabanlı uygulamaların sayısı arttı. Bunlar arasında web tabanlı yedekleme ve depolama vardır. Artık çok sayıda şirket bu tür hizmetler sunmaktadır, ancak bildiğimiz kadarıyla, bu hizmetler için istemcilerin hiçbiri kullanıcının yedekleme hizmeti anahtarını bir TPM'ye kilitlemesine izin vermemektedir. Bu yapıldıysa, TPM anahtarının birden çok makinede kopyalanarak yedeklenmesi kesinlikle güzel olurdu. Bu, geliştiriciler için bir fırsat gibi görünüyor.

Bir geliştirici bir anahtarı TPM'ye nasıl kilitler?

Bölüm 9 - Mirasçılar

DURUMU KULLAN: GİRİŞ ŞİFRELERİNİN SAKLANMASI

Tipik bir şifre dosyası, şifrelerin tuzlu karmalarını saklar. Doğrulama, sağlanan bir şifrenin tuzlanıp hash edilmesinden ve saklanan değerle karşılaştırılmasından oluşur. Hesaplama bir sır içermediğinden, şifre dosyasına çevrimdışı bir saldırıya tabidir.

Bu kullanım örneği, TPM tarafından oluşturulan bir HMAC anahtarı kullanır. Parola dosyası, gizli parolanın bir HMAC'sini depolar. Doğrulama, verilen şifrenin tuzlanmasından ve HMAC'den ve kayıtlı değerle karşılaştırılmasından oluşur. Çevrimdışı bir saldırgan HMAC anahtarına sahip olmadığından, saldırgan hesaplamayı gerçekleştirerek saldırı gerçekleştiremez.

Bu işe yarayabilir. TPM'nin gizli bir HMAC anahtarı varsa ve yalnızca TPM'im HMAC anahtarını biliyorsa, "İmzala (diğer adıyla TPM, özel anahtarıyla şifrelenir)" yerine "HMAC" koyabilirim. Ama bir sonraki satırda kendini tamamen tersine çeviriyor:

TPM2_Create, bir HMAC anahtarı belirterek

HMAC anahtarını belirtmem gerekirse TPM sırrı değildir. HMAC anahtarının gizli olmadığı gerçeği, TPM'nin sağladığı kriptografik yardımcı programlar hakkındaki bölümün bu olduğunu fark ettiğinizde mantıklıdır. SHA2, AES, HMAC veya RSA'yı kendiniz yazmak zorunda kalmak yerine, TPM'nin zaten var olanı yeniden kullanabilirsiniz.

Bölüm 10 - Anahtarlar

Bir güvenlik cihazı olarak, bir uygulamanın anahtarları bir donanım cihazında güvende tutarken kullanabilmesi , TPM'nin en büyük gücüdür. TPM, harici olarak oluşturulan anahtarları hem oluşturabilir hem de içe aktarabilir. Hem asimetrik hem de simetrik tuşları destekler.

Mükemmel! Bunu nasıl yapıyorsun!?

Anahtar Üretici

Muhtemelen, TPM'nin en büyük gücü, bir şifreleme anahtarı üretme ve bir donanım sınırı içinde sırrını koruma becerisidir. Anahtar oluşturucu, TPM'nin kendi rasgele sayı oluşturucusuna dayanır ve harici rasgelelik kaynaklarına dayanmaz. Böylece, yetersiz entropi kaynağı ile zayıf yazılım yazılımına dayanan zayıflıkları ortadan kaldırır.

TPM'nin şifreleme anahtarları oluşturma ve sırlarını bir donanım sınırı içinde koruma yeteneği var ? Öyle mi, nasıl?

Bölüm 12 - Platform Yapılandırma Kayıtları

Yetkilendirme için PCR'ler

DURUMU KULLANIN: PLATFORM DURUMUNA SABİT DİSK ŞİFRELEME ANAHTARINI KAPATMA

Tam disk şifreleme uygulamaları, bir TPM şifreleme anahtarını koruyorsa, aynı diskte saklanmasına kıyasla yalnızca bir parola ile korunursa çok daha güvenlidir. İlk olarak, TPM donanımının anti-çekiçleme koruması vardır (TPM sözlük saldırı korumasının ayrıntılı bir açıklaması için Bölüm 8'e bakın), bu da parola üzerinde kaba kuvvet saldırısını pratik değildir. Yalnızca yazılım tarafından korunan bir anahtar, zayıf bir parolaya karşı çok daha savunmasızdır. İkincisi, diskte depolanan bir yazılım anahtarının çalınması çok daha kolaydır. Diski (veya diskin yedeğini) alın ve anahtarı alın. TPM anahtarı tuttuğunda, tüm platform veya en azından disk ve ana kartın çalınması gerekir.

Sızdırmazlık, anahtarın yalnızca bir parola ile değil, bir ilkeyle de korunmasına izin verir. Tipik bir ilke, anahtarı mühürleme sırasında geçerli olan PCR değerlerine (yazılım durumu) kilitler. Bu, ilk önyüklemede durumun tehlikeye atılmadığını varsayar. İlk önyüklemede mevcut olan önceden yüklenmiş herhangi bir kötü amaçlı yazılım, PCR'lerde ölçülür ve böylece anahtar, tehlikeye atılmış bir yazılım durumuna mühürlenir. Daha az güven duyan bir kuruluş, standart bir disk görüntüsüne sahip olabilir ve bu görüntüyü temsil eden PCR'lere mühürlenebilir. Bu PCR değerleri, muhtemelen daha güvenilir bir platformda önceden hesaplanacaktır. Daha da karmaşık bir kuruluş, TPM2_PolicyAuthorize kullanır ve bir dizi güvenilir PCR değerini yetkilendiren birkaç bilet sağlar. Politika yetkisi ve PCR kırılganlığı sorununu çözmek için uygulanmasının ayrıntılı bir açıklaması için Bölüm 14'e bakın.

Bir parola anahtarı da koruyabilse de, TPM anahtar parolası olmasa bile bir güvenlik kazancı vardır. Saldırgan, TPMkey parolası sağlamadan platformu başlatabilir, ancak işletim sistemi kullanıcı adı ve parolası olmadan oturum açamaz. OSsecurity verileri korur. Saldırgan, işletim sistemi oturum açma güvenliğini aşmak için sabit sürücü yerine canlı bir DVD veya USB çubuğundan alternatif bir işletim sistemi başlatabilir. Ancak, bu farklı önyükleme yapılandırması ve yazılımı PCR değerlerini değiştirecektir. Bu yeni PCR'ler mühürlenen değerlerle eşleşmediğinden, TPM şifre çözme anahtarını serbest bırakmaz ve sabit sürücünün şifresi çözülemez.

Mükemmel! Bu tam da istediğim kullanım durumu. Ayrıca Microsoft'un TPM'yi. Nasıl yaparım!?

Bu yüzden tüm kitabı okudum ve yararlı hiçbir şey sağlamadı. Oldukça etkileyici çünkü 375 sayfa. Kitabın ne içerdiğini merak ediyorsunuz - ve geriye dönüp baktığımda hiçbir fikrim yok.

Bu nedenle, TPM'yi programlamak için eksiksiz kılavuzdan vazgeçip bunun yerine Microsoft'un bazı belgelerine dönüyoruz:

Gönderen Microsoft TPM Platformu Kripto-Sağlayıcı Toolkit . Tam olarak yapmak istediğim şeyden bahsediyor:

Onay Anahtarı veya EK

EK, platform için güvenilir bir kriptografik tanımlayıcı sağlamak üzere tasarlanmıştır. Bir kuruluş, kuruluşundaki tüm PC'lerin TPM'lerine ait Onay Anahtarlarının bir veritabanını tutabilir veya bir veri merkezi yapı denetleyicisi, tüm blade'lerde TPM'lerin veritabanına sahip olabilir. Windows'ta, EK'nin genel bölümünü okumak için "Windows 8'de Platform Şifreleme Sağlayıcısı" bölümünde açıklanan NCrypt sağlayıcısını kullanabilirsiniz.

TPM'nin içinde bir yerde bir RSA özel anahtarı bulunur. O anahtar orada kilitli - dış dünya tarafından asla görülmeyecek. TPM'nin kendi özel anahtarıyla bir şeyi imzalamasını istiyorum (yani, özel anahtarıyla şifreleyin).

Bu yüzden var olabilecek en temel işlemi istiyorum :

görüntü açıklamasını buraya girin

Özel anahtarınızla bir şeyi şifreleyin. Daha karmaşık şeyleri (henüz) istemiyorum:

  • PCR durumuna göre "mühürleme"
  • bir anahtar oluşturmak ve onu geçici veya kalıcı bir bellekte saklamak
  • simetrik bir anahtar oluşturmak ve bunu TPM'ye yüklemeye çalışmak

Bir TPM'nin yapabileceği en temel işlemi istiyorum. Nasıl yapılacağına dair herhangi bir bilgi almak neden imkansız?

Rastgele veri alabilirim

Sanırım RSA imzalamanın TPM'nin yapabileceği en temel şey olduğunu söylediğimde gevezelik ediyordum. En TPM yapmak istenebilir temel şey bana rastgele bayt vermektir. Yani ben nasıl anladım var:

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;
}

Fantezi Şey

TPM kullanan kişilerin hacminin çok düşük olduğunun farkındayım. Bu yüzden Stackoverflow'da kimsenin cevabı yok. Bu yüzden, genel sorunuma bir çözüm bulmakta gerçekten fazla açgözlü olamıyorum. Ama gerçekten yapmak istediğim şey, bazı verileri "mühürlemek" :

görüntü açıklamasını buraya girin

  • TPM'ye bazı verileri sunun (örneğin, 32 bayt anahtar malzeme)
  • TPM'nin verileri şifrelemesini ve bazı opak blob yapısını döndürmesini sağlayın
  • daha sonra TPM'den blob'un şifresini çözmesini isteyin
  • şifre çözme yalnızca TPM'nin PCR kayıtları, şifreleme sırasındaki ile aynıysa çalışır.

Diğer bir deyişle:

Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
   //...
}

Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
   //...
}

Cryptography Next Gen (Cng, aka BCrypt) TPM'yi destekler

Windows'taki orijinal Cryptography API, Crypto API olarak biliniyordu.

Windows Vista'dan başlayarak, Crypto API, Cryptography API: Next Generation ile değiştirildi (dahili olarak BestCrypt olarak bilinir , BCrypt olarak kısaltılır , parola karma algoritması ile karıştırılmamalıdır ).

Windows iki BCrypt sağlayıcısıyla birlikte gelir :

Platform Kripto sağlayıcı MSDN'de belgelenen, ancak 2012 Microsoft Research sitesinden belgeleri var:

TPM Platformu Şifreleme Sağlayıcı Araç Seti

TPM Platformu Şifreleme Sağlayıcısı ve Araç Seti, Windows 8'de TPM ile ilgili işlevselliği kullanmak için örnek kod, yardımcı programlar ve belgeler içerir. Açıklanan alt sistemler arasında TPM destekli Crypto-Next-Gen (CNG) platformu şifreleme sağlayıcısı ve doğrulama hizmeti sağlayıcıları yer alır yeni Windows özelliklerini kullanabilir. Hem TPM1.2 hem de TPM2.0 tabanlı sistemler desteklenir.

Microsoft'un niyeti ile yüzey TPM kripto işlevselliğine gibi görünüyor Microsoft Platformu şifreleme sağlayıcısı arasında Kriptografi NG API.

Microsoft BCrypt kullanarak genel anahtar şifreleme

Verilen:

ileriye giden bir yol, Microsoft Cryptography Next Gen API kullanarak dijital imzalamanın nasıl yapılacağını bulmak olabilir .

Bir sonraki adımım, standart sağlayıcıyı ( MS_PRIMITIVE_PROVIDER) kullanarak bir RSA genel anahtarıyla BCrypt'te şifreleme yapacak kodu bulmak olacak . Örneğin:

  • 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

Bu kodun çalışmasıyla, TPM Sağlayıcısını ( MS_PLATFORM_CRYPTO_PROVIDER) kullanmaya geçebilirim .

22.02.2016: Ve Apple'ın kullanıcı verilerinin şifresini çözmeye mecbur kalmasıyla, TPM'nin icat edildiği en basit görevi, bir şeyi şifrelemesini nasıl sağlayacağına dair yenilenen bir ilgi var.

Kabaca bir arabaya sahip olan herkese eşdeğerdir, ancak kimse nasıl başlatılacağını bilmiyor. 1. Adımı geçebilseydik, gerçekten yararlı ve harika şeyler yapabilir .

Bonus Okuma


Bağlama (şifreleme) için açık bir işlev yoktur ve buna da gerek yoktur. Sadece TPM'de bir bağlama anahtarı oluşturursunuz ve genel kısmını sistem rsa şifreleme işlevi ("RSA / ECB / OAEPWithSHA1AndMGF1Padding") ile simetrik bir şifreleme anahtarını şifrelemek ve doğru yapıda ("TcTssConstants.TSS_ENCDATA_BIND") kaydetmek için kullanırsınız. Sek'i ayırmak (şifresini çözmek) için, TPM'lerin çözme işlevini ve sek'i istediğiniz simetrik şifreleme işlevinde kullanın. Bunun için bir süre önce yaptığım oldukça eski bir kod tabanım var
evildead

Wikipedia'dan, Bağlama - bir depolama anahtarından türetilen benzersiz bir RSA anahtarı olan TPM bağlama anahtarını kullanarak verileri şifreler. en.wikipedia.org/wiki/Trusted_Platform_Module komutların bu çifti (TSpi_Data_Bind / TPM_UnBind) gibi Sesler ... ihtiyaçlarınız için yeterli olmalı
Alex Mazzariol

1
TPM'yi doğrudan kullanmanız gerektiğini düşünmüyorum. Standart CNG / NCryptXXX API'leri ve "Microsoft Platform Crypto Provider" (son Windows işletim sistemi platformları için ve tabii ki donanım iyi ve etkinse) aracılığıyla desteklenir. Belki "TPM Platformu Şifreleme Sağlayıcı Araç Setine buradan bakabilirsiniz: research.microsoft.com/en-us/downloads/… ayrıca şunu da kontrol edin: tiw2013.cse.psu.edu/slides/…
Simon Mourier

CryptProtectData mutlaka TPM'yi kullanmaz. Öte yandan, TPM için geçerli bir CNG veya CSP tanıtıcısı alabilirseniz, bunu kripto işlevlerinde kullanabilirsiniz.
Michael Chourdakis

1
@ b3nj1 Hayır değildim; soruya kimse cevap veremedi.
Ian Boyd

Yanıtlar:


7

Astar

Aşağıdakilerin tümü TPM 1.2 hakkındadır. Microsoft'un gelecekteki tüm Windows sürümleri için bir TPM 2.0 gerektirdiğini unutmayın. 2.0 nesli temelde 1.2'den farklıdır.

TPM tasarım ilkeleri nedeniyle tek satırlık bir çözüm yoktur. TPM'yi sınırlı kaynaklara sahip bir mikro denetleyici olarak düşünün. Ana tasarım hedefi, hala güvenli iken ucuz olmaktı. Böylece TPM, güvenli bir işlem için gerekli olmayan tüm mantıktan koparıldı. Eğer en azından bazı az ya da çok olması Dolayısıyla bir TPM sadece çalışıyor şişman yazılım doğru sırada komutları çok veren,. Ve bu komut dizileri çok karmaşık hale gelebilir. Bu nedenle TCG, iyi tanımlanmış bir API ile TSS'yi belirledi. Java yoluna gitmek isterseniz, yüksek seviyeli bir Java API'si bile var . C # / .net için benzer bir projenin farkında değilim

Geliştirme

Sizin durumunuzda, IBM'in yazılım TPM'sine bakmanızı öneririm.

Pakette çok kullanışlı 3 bileşen bulacaksınız:

  • bir yazılım TPM öykünücüsü
  • hafif bir tpm lib
  • bazı temel komut satırı yardımcı programları

Yazılım TPM öykünücüsüne ihtiyacınız yoktur, ayrıca makinenin HW TPM'sine de bağlanabilirsiniz. Bununla birlikte, verilen komutları durdurabilir ve yanıtlara bakabilir, böylece nasıl birleştirildiklerini ve komut özelliklerine nasıl karşılık geldiklerini öğrenebilirsiniz.

Yüksek seviye

Ön koşullar:

  1. TPM etkinleştirildi
  2. TPM sürücüsü yüklendi
  3. TPM'nin sahipliğini aldınız

Bir blobu mühürlemek için aşağıdakileri yapmanız gerekir:

  1. bir anahtar oluştur
  2. anahtar blobu bir yerde saklayın
  3. anahtarın TPM'ye yüklendiğinden emin olun
  4. blob'u mühürle

Mühür kaldırmak için yapmanız gerekenler:

  1. anahtar blob'u edinin
  2. anahtarı TPM'ye yükleyin
  3. mühürlü damlacığı açmak

Anahtar blobu, korumalı baytları depolamak için kullandığınız veri yapınızda saklayabilirsiniz.

İhtiyaç duyduğunuz TPM komutlarının çoğu yetkili komutlardır. Bu nedenle, gerektiğinde yetkilendirme oturumları oluşturmanız gerekir. AFAIR bunlar çoğunlukla OSAP oturumlarıdır.

TPM komutları

Şu anda bir hata ayıklama sürümünü çalıştıramıyorum, bu yüzden size tam sırayı sağlayamıyorum. Öyleyse , bunu kullanmanız gereken sırasız bir komut listesi olarak düşünün :

  • TPM_OSAP
  • TPM_CreateWrapKey
  • TPM_LoadKey2
  • TPM_Seal

Mevcut PCR değerlerini de okumak istiyorsanız:

  • TPM_PCRRead

Microsoft, TPM'yi kullanmak için kendi C # .NET yönetimli kitaplığına sahiptir . Ayrıca , gerçek bir TPM yoksa, yönetilen kitaplığın hata ayıklama alternatifi olarak bağlanabileceği bir TPM öykünücüsü vardır . Ayrıca, TPM'yi kullanmak için belgeler ve örnek kod içeren TPM Platform Provider Toolkit'e de sahiptirler . Şimdi sadece birisi baytları şifrelemek için TPM'nin nasıl kullanılacağını anlayabilseydi.
Ian Boyd

İlk iki bağlantınız yalnızca TPM 2.0'dır. Bunları kullanmak istiyorsan, korkarım yardım edemem.
Scolytus

4

Güvenilir ve Şifreli Anahtarlar

Güvenilir ve Şifrelenmiş Anahtarlar, mevcut çekirdek anahtarlık hizmetine eklenen iki yeni anahtar türüdür. Bu yeni türlerin her ikisi de değişken uzunluklu simetrik anahtarlardır ve her iki durumda da tüm anahtarlar çekirdekte oluşturulur ve kullanıcı alanı yalnızca şifrelenmiş blobları görür, depolar ve yükler. Güvenilir Anahtarlar, daha fazla güvenlik için bir Güvenilir Platform Modülü (TPM) yongasının bulunmasını gerektirirken, Şifreli Anahtarlar herhangi bir sistemde kullanılabilir. Tüm kullanıcı seviyesi blobları, kolaylık sağlamak için hex ascii biçiminde görüntülenir ve yüklenir ve bütünlük doğrulanır.

Güvenilir Anahtarlar, anahtarları oluşturmak ve mühürlemek için bir TPM kullanır. Anahtarlar, TPM'de 2048 bitlik bir RSA anahtarı altında mühürlenir ve isteğe bağlı olarak belirtilen PCR (bütünlük ölçümü) değerlerine göre mühürlenir ve yalnızca PCR'ler ve blob bütünlüğü doğrulamaları eşleşirse TPM tarafından mühürlenmez. Yüklenen bir Güvenilir Anahtar, yeni (gelecekteki) PCR değerleriyle güncellenebilir, böylece anahtarlar, çekirdek ve initramfs güncellendiğinde olduğu gibi, yeni pcr değerlerine kolayca taşınır. Aynı anahtar, farklı PCR değerleri altında birçok kaydedilmiş blob'a sahip olabilir, bu nedenle birden çok önyükleme kolayca desteklenir.

Varsayılan olarak, güvenilen anahtarlar, varsayılan yetkilendirme değerine (20 sıfır) sahip olan SRK altında mühürlenir. Bu pantolon faydasının ile takeownership anda ayarlanabilir: tpm_takeownership -u -z.

Usage:
    keyctl add trusted name "new keylen [options]" ring
    keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
    keyctl update key "update [options]"
    keyctl print keyid

    options:
    keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
    keyauth=   ascii hex auth for sealing key default 0x00...i
        (40 ascii zeros)
    blobauth=  ascii hex auth for sealed data default 0x00...
        (40 ascii zeros)
    blobauth=  ascii hex auth for sealed data default 0x00...
        (40 ascii zeros)
    pcrinfo=   ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
    pcrlock=   pcr number to be extended to "lock" blob
    migratable= 0|1 indicating permission to reseal to new PCR values,
                default 1 (resealing allowed)

keyctl printstandart TPM_STORED_DATA biçiminde olan mühürlü anahtarın ascii onaltılık bir kopyasını döndürür. Yeni anahtarlar için anahtar uzunluğu her zaman bayt cinsindendir. Güvenilen Anahtarlar 32 - 128 bayt (256 - 1024 bit) olabilir, üst sınır, gerekli tüm yapı / dolgu ile 2048 bit SRK (RSA) anahtar uzunluğuna uymaktır.

Şifrelenmiş anahtarlar bir TPM'ye bağlı değildir ve şifreleme / şifre çözme için AES kullandıklarından daha hızlıdırlar. Çekirdeğin oluşturduğu rastgele sayılardan yeni anahtarlar oluşturulur ve belirli bir 'ana' anahtar kullanılarak şifrelenir / şifreleri çözülür. "Ana" anahtar, bir güvenilir anahtar veya kullanıcı anahtarı türü olabilir. Şifrelenmiş anahtarların temel dezavantajı, güvenilir bir anahtarda köklenmemişlerse, yalnızca onları şifreleyen kullanıcı anahtarı kadar güvenli olmalarıdır. Bu nedenle, ana kullanıcı anahtarı, mümkün olduğu kadar güvenli bir şekilde, tercihen önyüklemenin başlarında yüklenmelidir.

Şifrelenmiş anahtarların şifresi çözülen kısmı, basit bir simetrik anahtar veya daha karmaşık bir yapı içerebilir. Daha karmaşık yapının formatı uygulamaya özeldir ve "format" ile tanımlanır.

Usage:
    keyctl add encrypted name "new [format] key-type:master-key-name keylen"
        ring
    keyctl add encrypted name "load hex_blob" ring
    keyctl update keyid "update key-type:master-key-name"

format:= 'default | ecryptfs'
key-type:= 'trusted' | 'user'

Güvenilir ve şifrelenmiş anahtar kullanımına örnekler

32 bayt uzunluğunda "kmk" adlı güvenilir bir anahtar oluşturun ve kaydedin:

$ keyctl add trusted kmk "new 32" @u
440502848

$ keyctl show
Session Keyring
       -3 --alswrv    500   500  keyring: _ses
 97833714 --alswrv    500    -1   \_ keyring: _uid.500
440502848 --alswrv    500   500       \_ trusted: kmk

$ keyctl print 440502848
0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
e4a8aea2b607ec96931e6f4d4fe563ba

$ keyctl pipe 440502848 > kmk.blob

Kaydedilmiş blob'dan güvenilir bir anahtar yükleyin:

$ keyctl add trusted kmk "load `cat kmk.blob`" @u
268728824

$ keyctl print 268728824
0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
e4a8aea2b607ec96931e6f4d4fe563ba

Güvenilir bir anahtarı yeni pcr değerleri altında yeniden mühürleyin:

$ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
$ keyctl print 268728824
010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8

Güvenilir anahtarların ilk tüketicisi, dosya meta verilerinin HMAC koruması için önyükleme sırasında yüksek kaliteli bir simetrik anahtara ihtiyaç duyan EVM'dir. Güvenilir bir anahtarın kullanılması, EVM anahtarının kullanıcı seviyesindeki bir problem tarafından tehlikeye atılmadığına dair güçlü garantiler sağlar ve belirli önyükleme PCR değerlerine göre mühürlendiğinde, önyükleme ve çevrimdışı saldırılara karşı koruma sağlar. Yukarıdaki güvenilir anahtar olan "kmk" yi kullanarak şifrelenmiş bir "evm" anahtarı oluşturun ve kaydedin:

seçenek 1: "biçim" i atlamak

$ keyctl add encrypted evm "new trusted:kmk 32" @u
159771175

seçenek 2: 'format'ı' varsayılan 'olarak açıkça tanımlama

$ keyctl add encrypted evm "new default trusted:kmk 32" @u
159771175

$ keyctl print 159771175
default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

$ keyctl pipe 159771175 > evm.blob

Kaydedilmiş blob'dan şifrelenmiş bir "evm" anahtarı yükleyin:

$ keyctl add encrypted evm "load `cat evm.blob`" @u
831684262

$ keyctl print 831684262
default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

Güvenilir ve şifrelenmiş anahtarların disk ve dosya şifreleme gibi diğer kullanımları da tahmin edilmektedir. Özellikle, bir eCryptfs dosya sistemini bağlamak için şifrelenmiş anahtarları kullanmak için yeni 'ecryptfs' biçimi tanımlanmıştır. Kullanımla ilgili daha fazla ayrıntı, 'Belgeler / güvenlik / anahtarlar-ecryptfs.txt' dosyasında bulunabilir.


Bu iki yeni anahtar türünün nereye eklendiğine dair bir fikriniz var mı? Hangi versiyondan bahsediyorum. Şu anda 1.2 (şirket paketleri) kullanıyorum ve bu bunları desteklemiyor. Belki 1.5+?
Acapulco

1
Bu gönderinin kaynağı nedir? Son, bir belgeye atıfta bulunuyorDocumentation/security/keys-ecryptfs.tx
goodguys_activate

Bunların hepsi bir komut satırı programına yapılan çağrılar gibi görünüyor. TPM'nin nasıl kullanılacağına dair bir kod göremiyorum.
Ian Boyd

3

Bir makinenin TPM modülünü kullanarak baytları nasıl şifreleyebilirim?

Niyetinize ve koşullarınıza bağlıdır:

  • Ne tür bir TPM'ye sahipsiniz (1 aileli veya 2 aileli)?
  • TPM hangi durumda? Sahiplendi mi? Sağlandı mı?
  • Programlama diliniz nedir?
  • Şifrelemek mi yoksa imzalamak mı istiyorsunuz? (bu, sorunun geri kalanından belirsiz)
  • Şifrelemek istediğiniz veriler ne kadar büyük?
  • Simetrik anahtar mı yoksa asimetrik anahtar mı kullanmak istiyorsunuz?
  • TPM'de zaten var olan bir anahtarı mı kullanmak istiyorsunuz yoksa önce anahtarı oluşturmasını mı istiyorsunuz?
  • "Şifrele" derken belki "anahtarı sarmak" mı demek istiyorsunuz?
  • Şifrelenmiş verileri, yalnızca sistem aynı yapılandırmaya geri döndüğünde şifresinin çözülebilmesi için sistem yapılandırmasına kilitlemek istiyor musunuz?
  • Şifre çözme için yetkilendirme gerektirmek istiyor musunuz?
  • Belki de hiç şifrelemeniz gerekmez, bunun yerine verileri TPM içinde depolamanız gerekir?
  • Verileri TPM içinde depoluyorsanız, erişim için yetkilendirme veya sistemin belirli bir konfigürasyonda olmasını mı istiyorsunuz?

Bu kullanım durumlarının her biri (ve daha fazlası vardır) - veya bunların bir kombinasyonu - farklı bir uygulama yolu sunar. TPM'yi kriptografik cihazlardan oluşan bir İsviçre Çakısı olarak düşünün: onunla yapamayacağınız pek bir şey yok, ancak kullanım kolaylığı bu çok yönlülükten zarar görüyor. Soru, şifreleme, imzalama ve sistem konfigürasyonuna kilitleme arasında gidip gelmeye devam ediyor, ancak bu cevabın ana kısmı, Seal komutunun soruda açıklanan ihtiyaçların çoğunu kapsadığını dikkate alacaktır.

Şimdi bunu bir adım daha ileri götürme zamanı. Yalnızca yerel TPM tarafından şifresi çözülebilen bazı verileri (örneğin, sabit sürücü şifreleme ana anahtarı) şifrelemek istiyorum.

Bind komutunun amacı budur (TPM 2 için Oluştur komutunun yerini almıştır). TPM'ye bağlı bir anahtardan türetilen ve onunla (veya doğrudan donanıma bağlı bir anahtarla) şifreleyen bir anahtar yüklersiniz. Bu şekilde, verilerin şifresi yalnızca aynı TPM'ye erişimle çözülebilir.

Başka bir deyişle, Android için aşağıdaki blok şemasında Qualcomm Trusted Execution Environment'ı (TEE) Windows'taki TPM ile değiştirmek istiyorum:

Tüm bu süreci tekrarlamanın iyi bir fikir olup olmadığından emin değilim. Birincisi, sürecin herhangi bir yerinde bir imzalama işlemi kullanmaya gerek yoktur. Görünüşe göre, Android 5 geliştirilirken, Keystore API imzalama ve doğrulama işlemleriyle sınırlıydı . En iyi tahminim, disk şifreleme ekibinin ellerinde olanla çalışmak için ellerinden gelenin en iyisini yaptıkları ve ara anahtarlardan birinin , depolanmış bir TEE anahtarı kullanılarak bir imzalama işlemi ile türetildiği ve böylece tüm süreci bir donanıma bağladığı bir algoritma geliştirdiği. bağlı anahtar yalnızca platformda mevcuttur - o sırada bunu yapmanın tek yolu imzalamaktı. Bununla birlikte, bir TPM'ye erişiminiz varsa, kendinizi bu şekilde kısıtlamanıza gerek yoktur, bu da size ihtiyaç duyduğunuzdan daha fazla yetenek sağlar!

TPM'nin veri imzalama yapmadığını anlıyorum

Bu yanlıştır, TPM'nin her iki sürümü de imzalamayı destekler.

(veya eğer öyleyse, aynı veriyi imzalamanın her seferinde aynı ikili çıktıyı vereceğini garanti etmez)

Bu anlamlı değil. Aynı anahtara sahip aynı veriyi imzalanması olacak aynı imza üretir. İmzalama işlemini, tek seferde karışacak olan alıntı işlemi ile karıştırıyor olabilirsiniz.

Bu nedenle, "RSA imzalamayı", "256 bitlik bir blob'u donanıma bağlı bir anahtarla şifrelemek" ile değiştirmeye istekli olacağım.

TPM ile her ikisi de mümkün olsa da bu aslında tercih edilen seçenek olmalıdır. Yukarıyı görmek.

Sorun, TPM programlamasının MSDN'de tamamen belgelenmemiş olmasıdır. Herhangi bir işlemi gerçekleştirmek için kullanılabilir API yoktur.

Maalesef belgelenecek çok şey yok. Win API, sürücüden bir seviye kaldırılan birkaç TBS işleviyle sınırlıdır.

Bunun yerine, Trusted Computing Group'un Yazılım Yığınının (TSS olarak da bilinir) bir kopyasını bulmanız, TPM'ye hangi sırayla yüklerle birlikte hangi komutların gönderileceğini bulmanız ve komutları doğrudan göndermek için Window'un Tbsip_Submit_Command işlevini çağırmanız gerekir:

Aslında hayır, TSS'niz olsaydı kullanmak zorunda kalmazdınız Tbsip_submit_Command(). Bir TSS'ye sahip olmanın tüm noktası budur - düşük seviyeli ayrıntılar soyutlanmıştır.

Windows, eylemleri gerçekleştirmek için daha yüksek düzeyde API'ye sahip değildir.

TPM 1 için hala doğru, ancak TPM 2 için TSS.MSR var .

Bu, sabit sürücünüze SATA I / O komutları göndererek bir metin dosyası oluşturmaya çalışmanın ahlaki karşılığıdır.

Doğru.

Neden sadece Pantolon kullanmıyorsunuz? Bu kodla ilgili sorun, Windows dünyasına taşınabilir olmamasıdır. Örneğin, Delphi'den kullanamazsınız, C # üzerinden kullanamazsınız. Şunları gerektirir: OpenSSL, pThread

Bunun aşılmaz bir meydan okuma olduğu net değil. Birlikte çalışma yoluyla TrouSerS'e erişmek, tüm veri yapılandırma kodunu yeniden yazmak yerine tercih edilmelidir. Ayrıca doTSSsoruyu yazarken de vardı.

TPM kullanarak verileri şifrelemek için eşdeğer kod nedir? Muhtemelen TPM_seal komutunu içerir. Verileri mühürlemek istemediğimi düşünmeme rağmen, onu bağlamak istediğimi düşünüyorum:

Soru, iki komut arasındaki farkı açıklayan bir alıntı içeriyor, bu yüzden fazla kafa karışıklığı olmamalı. Mühürleme, verilerin mühürlenmemesi için sistem durumunun aynı olması gerektiğine dair eklenen kısıtla, bağlayıcıya benzer.

Aynı şekilde şunları sağlayabildim:

Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
   //...
   CryptProtectData(...); 
   //...
}

birisi karşılık gelen eşdeğeri sağlayabilir:

Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
   //...
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   //...snip...
   Tbsip_Submit_Command(...);
   //...
}

Sistem LSA'da kilitli bir anahtarın TPM'de kilitli olması dışında aynı şey mi oluyor?

İlk olarak, TPM'nin birbirleriyle tamamen uyumsuz olan iki ana sürümü olduğunu belirtmek gerekir. Dolayısıyla, TPM 1 için yazmış olabileceğiniz neredeyse hiçbir kod, TPM 2 için çalışmayacaktır. TBS API, ikisi arasındaki tek ortak koddur ve Microsoft açısından adil olmak gerekirse, API'nin hiç büyümemesinin nedenlerinden biri bu olabilir. Cevabın ana kısmı, iki nedenden dolayı TPM 1 kodunu sunacaktır:

  • Soru, TPM 1'e özgü kavramlarla yüklenmiştir, bu nedenle TPM 1 kullanan kişilerin onları aramak için buraya inme olasılığı daha yüksektir
  • TPM 2 için TSS'nin bir Microsoft uygulaması vardır.

İkincisi, soruyu daha spesifik hale getirelim. Bunu şu şekilde yeniden yorumluyorum:

How do I write code in C#, using only the TBS API, to interface with
an already owned and provisioned TPM to, without user interaction,
encrypt no more than 128 bytes of arbitrary data with an asymmetric
key already resident in the TPM and bound to it, but not protected
with a password, so that in order to decrypt the data the system may
need to be in the same state it was in at encryption time based on an
easily configurable variable?

Seal komutu, PCR seçim boyutu sıfıra ayarlandığında Bind komutuyla aynı işlevi gerçekleştirdiğinden, bunun için en uygun olanıdır, ancak PCR seçimi, istediğiniz herhangi bir PCR'yi içerecek şekilde kolayca değiştirilebilir. Bind komutunun neden spesifikasyona dahil edildiğini merak ediyor ve belirtildiği gibi TPM 2 spesifikasyonunda kaldırıldı ve ikisi bir Oluşturma komutunda birleştirildi.

Verileri yalnızca TBS işlevleriyle şifrelemek için TPM 1.2 Seal komutunu kullanmanın C # kodunu burada bulabilirsiniz (not: bu kod test edilmemiştir ve hata ayıklama olmadan çalışması olası değildir) :

[DllImport ("tbs.dll")]
unsafe static extern UInt32 Tbsi_Context_Create (UInt32 * version, IntPtr * hContext);

[DllImport ("tbs.dll")]
unsafe static extern UInt32 Tbsip_Context_Close (IntPtr hContext);

[DllImport ("tbs.dll")]
unsafe static extern UInt32 Tbsip_Submit_Command (
    IntPtr hContext, UInt32 Locality, 
    UInt32 Priority, 
    byte * pCommandBuf, 
    UInt32 CommandBufLen, 
    byte * pResultBuf, 
    UInt32 * pResultBufLen);

byte[] ProtectBytes_TPM (byte[] plaintext) {

    void AddUInt32Reversed (byte[] a, System.UInt32 o, ref int i) {
        byte[] bytes = System.BitConverter.GetBytes (o);
        Array.Reverse (bytes);
        Array.Copy (bytes, 0, a, i, bytes.Length);
        i += bytes.Length;
    }
    void AddUInt16Reversed (byte[] a, System.UInt16 o, ref int i) {
        byte[] bytes = System.BitConverter.GetBytes (o);
        Array.Reverse (bytes);
        Array.Copy (bytes, 0, a, i, bytes.Length);
        i += bytes.Length;
    }
    void AddBool (byte[] a, byte b, ref int i) {
        a[i] = b;
        i += 1;
    }
    void AddBlob (byte[] a, byte[] b, ref int i) {
        Array.Copy (b, 0, a, i, b.Length);
        i += b.Length;
    }
    byte[] Xor (byte[] text, byte[] key) {
        byte[] xor = new byte[text.Length];
        for (int i = 0; i < text.Length; i++) {
            xor[i] = (byte) (text[i] ^ key[i % key.Length]);
        }
        return xor;
    }

    int offset;

    Random rnd = new Random ();

    IntPtr hContext = IntPtr.Zero;
    unsafe {
        UInt32 version = 1;
        IntPtr handle = hContext;
        UInt32 result = Tbsi_Context_Create ( & version, & handle);

        if (result == 0) {
            hContext = handle;
        }
    }

    byte[] cmdBuf = new byte[768];

    //OSAP
    System.UInt32 outSize;

    byte[] oddOsap = new byte[20];
    byte[] evenOsap = new byte[20];
    byte[] nonceEven = new byte[20];
    byte[] nonceOdd = new byte[20];
    System.UInt32 hAuth = 0;

    offset = 0;
    AddUInt16Reversed (cmdBuf, 0x00C1, ref offset);
    offset = 6;
    AddUInt32Reversed (cmdBuf, 0x0000000B, ref offset);

    offset = 2 + 4 + 4; //2 for tag, 4 for size and 4 for command code

    AddUInt16Reversed (cmdBuf, 0x0004, ref offset); //Entity Type SRK = 0x0004
    AddUInt32Reversed (cmdBuf, 0x40000000, ref offset); //Entity Value SRK = 0x40000000
    rnd.NextBytes (oddOsap);
    AddBlob (cmdBuf, oddOsap, ref offset);
    uint cmdSize = (System.UInt32) offset;
    offset = 2;
    AddUInt32Reversed (cmdBuf, cmdSize, ref offset);

    outSize = (System.UInt32) (Marshal.SizeOf (hAuth) + nonceEven.Length + evenOsap.Length);

    byte[] response = new byte[outSize];
    unsafe {
        UInt32 result = 0;

        //uint cmdSize = (uint)offset;
        uint resSize = outSize;
        fixed (byte * pCmd = cmdBuf, pRes = response) {
            result = Tbsip_Submit_Command (hContext, 0, 200, pCmd, cmdSize, pRes, & resSize);
        }
    }

    byte contSession = 0;
    System.UInt32 hKey = 0x40000000; //TPM_KH_SRK;
    System.UInt32 pcrInfoSize = 0;
    byte[] srkAuthdata = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    uint inDataSize = (uint) plaintext.Length;

    offset = 2 + 4 + 4; //2 for tag, 4 for size and 4 for return code
    byte[] hauthbytes = new byte[Marshal.SizeOf (hAuth)];
    Array.Copy (response, offset, hauthbytes, 0, hauthbytes.Length);
    Array.Reverse (hauthbytes);
    hAuth = System.BitConverter.ToUInt32 (hauthbytes, 0);
    offset += Marshal.SizeOf (hAuth);
    Array.Copy (response, offset, nonceEven, 0, nonceEven.Length);
    offset += nonceEven.Length;
    Array.Copy (response, offset, evenOsap, 0, evenOsap.Length);

    //shared-secret = HMAC(srk_auth, even_osap || odd_osap)
    byte[] sharedSecretBuf = new byte[evenOsap.Length + oddOsap.Length];
    Array.Copy (evenOsap, 0, sharedSecretBuf, 0, evenOsap.Length);
    Array.Copy (oddOsap, 0, sharedSecretBuf, evenOsap.Length, oddOsap.Length);
    System.Security.Cryptography.HMACSHA1 sharedSecretHmac = new System.Security.Cryptography.HMACSHA1 (srkAuthdata);
    byte[] sharedSecret = sharedSecretHmac.ComputeHash (sharedSecretBuf);

    byte[] authSha1InBuf = new byte[sharedSecret.Length + nonceEven.Length];
    Array.Copy (sharedSecret, 0, authSha1InBuf, 0, sharedSecret.Length);
    Array.Copy (nonceEven, 0, authSha1InBuf, sharedSecret.Length, nonceEven.Length);
    System.Security.Cryptography.SHA1Managed sha1 = new System.Security.Cryptography.SHA1Managed ();
    byte[] authSha1 = sha1.ComputeHash (authSha1InBuf);
    byte[] encAuth = Xor (srkAuthdata, authSha1);

    //inParamDigest = sha1(1S ~ 6S) 
    int paramInDigestInBufSize =
        sizeof (System.UInt32) + 
        encAuth.Length +
        Marshal.SizeOf (pcrInfoSize) +
        Marshal.SizeOf (inDataSize) +
        (int) inDataSize;
    byte[] paramInDigestInBuf = new byte[paramInDigestInBufSize];
    offset = 0;
    AddUInt32Reversed (paramInDigestInBuf, 0x00000017, ref offset);
    AddBlob (paramInDigestInBuf, encAuth, ref offset);
    AddUInt32Reversed (paramInDigestInBuf, 0x0, ref offset); //PCR info size
    AddUInt32Reversed (paramInDigestInBuf, inDataSize, ref offset);
    AddBlob (paramInDigestInBuf, plaintext, ref offset);

    byte[] paramInDigest = sha1.ComputeHash (paramInDigestInBuf);

    int pubAuthInBufSize = paramInDigest.Length + nonceEven.Length + nonceOdd.Length + Marshal.SizeOf (contSession);
    byte[] pubAuthInBuf = new byte[pubAuthInBufSize];

    offset = 0;
    AddBlob (pubAuthInBuf, paramInDigest, ref offset);
    AddBlob (pubAuthInBuf, nonceEven, ref offset);
    AddBlob (pubAuthInBuf, nonceOdd, ref offset);
    AddBool (pubAuthInBuf, contSession, ref offset);
    System.Security.Cryptography.HMACSHA1 pubAuthHmac = new System.Security.Cryptography.HMACSHA1 (sharedSecret);
    byte[] pubAuth = pubAuthHmac.ComputeHash (pubAuthInBuf);

    //Seal
    offset = 0;
    AddUInt16Reversed (cmdBuf, 0x00C2, ref offset); // TPM_TAG_RQU_AUTH1_COMMAND;
    offset = 6;
    AddUInt32Reversed (cmdBuf, 0x00000017, ref offset); // TPM_ORD_SEAL;
    offset = 2 + 4 + 4; //2 for tag, 4 for size and 4 for command code

    AddUInt32Reversed (cmdBuf, hKey, ref offset);
    AddBlob (cmdBuf, encAuth, ref offset);
    AddUInt32Reversed (cmdBuf, pcrInfoSize, ref offset);
    AddUInt32Reversed (cmdBuf, inDataSize, ref offset);
    AddBlob (cmdBuf, plaintext, ref offset);

    AddUInt32Reversed (cmdBuf, hAuth, ref offset);
    AddBlob (cmdBuf, nonceOdd, ref offset);
    AddBool (cmdBuf, contSession, ref offset);
    AddBlob (cmdBuf, pubAuth, ref offset);
    cmdSize = (System.UInt32) offset;
    offset = 2;
    AddUInt32Reversed (cmdBuf, cmdSize, ref offset);

    outSize = 768;
    uint responseSize = 0;

    response = new byte[outSize];
    unsafe {
        UInt32 result = 0;

        uint resSize = outSize;
        fixed (byte * pCmd = cmdBuf, pRes = response) {
            result = Tbsip_Submit_Command (hContext, 0, 200, pCmd, cmdSize, pRes, & resSize);
        }
        responseSize = resSize;
    }

    byte[] retBuffer = new byte[responseSize - 10];
    Array.Copy (response, 10, retBuffer, 0, retBuffer.Length);
    Tbsip_Context_Close (hContext);
    return retBuffer;

}

Kod Analizi:

[DllImport ("tbs.dll")]
...

Bunlar, Tbs.h dosyasında bulunan birkaç işlevden bazıları ve burada kullanacağımız yegane işlevler. Temel olarak, cihaza bir tanıtıcı açmanıza ve ham bayt gönderip alarak onunla iletişim kurmanıza izin verir.

    void AddUInt32Reversed (byte[] a, System.UInt32 o, ref int i) { ... }
    void AddUInt16Reversed (byte[] a, System.UInt16 o, ref int i) { ... }
    void AddBool (byte[] a, byte b, ref int i) { ... }
    void AddBlob (byte[] a, byte[] b, ref int i) { ... }

TPM büyük endian, Windows biraz endian. Bu nedenle, gönderdiğimiz herhangi bir veri için bayt sırasının tersine çevrilmesi gerekecektir. Burada sadece 32-bit ve 16-bit işaretsiz girişleri ters çevirme konusunda endişelenmemiz gerekiyor.

    ...
    UInt32 result = Tbsi_Context_Create ( & version, & handle);
    ...

Burada TPM ile konuşmak için bir tutamaç açmak için Tbsi_Context_Create () kullanıyoruz . TBS_CONTEXT_PARAMSParametresi bir TPM 1.2 örneğine konuşmak için 1 olarak ayarlanır ve biz ayarlayın şey bu olmalı bir işaretsiz 32 bit int alanıyla sadece bir C yapı olduğunu.

    byte[] cmdBuf = new byte[768];

Bu, TPM PC İstemci Spesifikasyonunda minimum arabellek boyutu olarak belirtilir . Buradaki ihtiyaçlarımız için fazlasıyla yeterli olacak.

TPM 1.2 Teknik Özellik Bölüm 3 şunları söylüyor:

TPM_Seal requires the encryption of one parameter (“Secret”). For the
sake of uniformity with other commands that require the encryption of
more than one parameter, the string used for XOR encryption is
generated by concatenating a nonce (created during the OSAP session)
with the session shared secret and then hashing the result.

Bu "gizli" parametreyi bir OSAP oturumu sırasında üretilen bir nonce kullanarak XOR şifrelememiz gerekir. Seal komut giriş tutamaçlarından biri de bir OSAP tanıtıcısıdır:

The authorization session handle used for keyHandle authorization.
Must be an OSAP session for this command.

Bu yüzden önce bu OSAP oturumunu kurmamız gerekiyor. OSAP, TPM 1.2 Teknik Özellik Bölüm 1'de açıklanmaktadır . OSAP veya Nesneye Özgü Yetkilendirme Protokolü, birden çok kez yetkilendirme gerektiren ancak her seferinde yetkilendirme sağlamak istemeyen bir TPM nesnesini kullanmak istediğiniz kullanım durumunu ele almak için icat edilmiştir: bunun yerine, buna dayanan bir OSAP oturumu kullanılır bir HMAC olan "paylaşılan sır" kavramı üzerineyanıt saldırılarını önlemek için nesne yetkilendirme verilerini her iki tarafta üretilen nonces ile karıştıran. Bu nedenle, "paylaşılan sır" bu oturumda yalnızca iki tarafça bilinir: oturumu başlatan taraf (kullanıcı) ve kabul eden taraf (TPM); ayrıca, "paylaşılan sır" ın aynı olması için her iki tarafın da aynı nesne yetkilendirme verilerine sahip olması gerekir; ayrıca, bir oturumda kullanılan "paylaşılan sır" başka bir oturumda geçersiz olacaktır. Spesifikasyondaki bu şema süreci açıklar:

OSAP

Bu özel durumda birden fazla oturum kullanmayacağız (aslında, bu parametre Seal komutuyla göz ardı edilir!) Ve kullanacağımız anahtar yetkilendirme gerektirmez, ancak maalesef yine de bir OSAP kurmak için spesifikasyona bağlıyız. oturum, toplantı, celse.

    offset = 0;
    AddUInt16Reversed (cmdBuf, 0x00C1, ref offset);
    offset = 6;
    AddUInt32Reversed (cmdBuf, 0x0000000B, ref offset);

    offset = 2 + 4 + 4; //2 for tag, 4 for size and 4 for command code

    AddUInt16Reversed (cmdBuf, 0x0004, ref offset); //Entity Type SRK = 0x0004
    AddUInt32Reversed (cmdBuf, 0x40000000, ref offset); //Entity Value SRK = 0x40000000
    rnd.NextBytes (oddOsap);
    AddBlob (cmdBuf, oddOsap, ref offset);
    uint cmdSize = (System.UInt32) offset;

TPM_OSAP komut işlenenleri şunlardır:

TPM_OSAP işlenenleri

Her TPM 1.2 komutu şu şekilde düzenlenmiştir:

  2 bytes       4 bytes             4 bytes
+---------+------------------+------------------+---------------------------
|   Tag   |       Size       |   Command code   |    Command body    ....
+---------+------------------+------------------+---------------------------

Etiket, izleyen şeyin girdi mi yoksa çıktı mı olduğunu ve komut parametrelerini izleyen herhangi bir kimlik doğrulama veri değeri olup olmadığını gösteren iki baytlık bir değerdir. TPM_OSAP için, spesifikasyona göre etiket TPM_TAG_RQU_COMMAND (0x00C1) olmalıdır, yani "yetkisiz bir komut".

Boyut, etiket ve boyutun kendisi de dahil olmak üzere, komutun boyutunu bayt cinsinden belirten dört baytlık bir değerdir. Bu değeri daha sonra hesapladıktan sonra ayarlayacağız.

Komut kodu, komut kimliği olarak sunulan dört baytlık bir değerdir: TPM'ye komutun geri kalanını nasıl yorumlayacağını söyler. Buradaki komut kodumuz TPM_OSAP (0x0000000B).

Ayarlanacak sonraki iki şey varlık türü ve varlık değeridir. TPM'de zaten var olan bir anahtarı kullanmak istediğimizden, varlık türü "SRK" (0x0004) kullanacağız ve TPM'nin halihazırda sahip olduğu varsayımı altında çalıştığımız için, anahtarın sahip olduğunu varsaymak güvenlidir. Spesifikasyona göre kalıcı tutamaç 0x40000000 altında yüklenen bir SRK, bu nedenle varlık değerimiz için bu kalıcı tutamaç değerini kullanacağız. (SRK, "Depolama Kök Anahtarı" anlamına gelir ve TPM'ye ait diğer anahtarların çoğunun türetildiği kök anahtardır)

    result = Tbsip_Submit_Command (hContext, 0, 200, pCmd, cmdSize, pRes, & resSize);

Son olarak komut boyutunu hesaplayıp ayarlayıp komutu gönderiyoruz.

    offset = 2 + 4 + 4; //2 for tag, 4 for size and 4 for return code
    byte[] hauthbytes = new byte[Marshal.SizeOf (hAuth)];
    Array.Copy (response, offset, hauthbytes, 0, hauthbytes.Length);
    Array.Reverse (hauthbytes);
    hAuth = System.BitConverter.ToUInt32 (hauthbytes, 0);
    offset += Marshal.SizeOf (hAuth);
    Array.Copy (response, offset, nonceEven, 0, nonceEven.Length);
    offset += nonceEven.Length;
    Array.Copy (response, offset, evenOsap, 0, evenOsap.Length);

TPM_OSAP üzerindeki TPM'den geri almamız gereken veriler:

TPM_OSAP yanıtı

Öyleyse geri dönüyoruz:

  • Ana komutumuzla (Seal) kullanmak için yetkilendirme kolu
  • nonceEven: ana komutla kullanmak için TPM tarafından üretilen nonce
  • nonceEvenOSAP: TPM_OSAP komutunu göndermeden önce bizim tarafımızda ürettiğimiz nonce'ye karşı olan OSAP nonce. Bu iki nonce, "paylaşılan sırrı" oluşturmak için kullanılacaktır.

Bu değerleri çıkarıyoruz ve değişkenlerde saklıyoruz.

    byte[] sharedSecretBuf = new byte[evenOsap.Length + oddOsap.Length];
    Array.Copy (evenOsap, 0, sharedSecretBuf, 0, evenOsap.Length);
    Array.Copy (oddOsap, 0, sharedSecretBuf, evenOsap.Length, oddOsap.Length);
    System.Security.Cryptography.HMACSHA1 sharedSecretHmac = new System.Security.Cryptography.HMACSHA1 (srkAuthdata);
    byte[] sharedSecret = sharedSecretHmac.ComputeHash (sharedSecretBuf);

Sonra "paylaşılan sırrı" hesaplıyoruz. Spesifikasyona göre, hesaplamaya giren değerler iki OSAP noncesidir (biri kullanıcı tarafından, diğeri TPM tarafından oluşturulan) ve kullanmak istediğimiz anahtarın yetkilendirme değeridir - SRK. Geleneksel olarak, SRK kimlik doğrulama değeri "iyi bilinen kimlik doğrulama" dır: sıfırlanmış 20 baytlık bir arabellek. Teknik olarak, TPM'nin sahipliğini alırken bu değer başka bir şeye değiştirilebilir, ancak bu pratikte yapılmadığından, "iyi bilinen kimlik doğrulama" değerinin iyi olduğunu güvenle varsayabiliriz.

Şimdi, TPM_Seal komutuna neyin girdiğine bir göz atalım:

TPM_Seal

Bu parametrelerin çoğunun oluşturulması önemsizdir, ikisi dışında: encAuthve pubAuth. Bunlara tek tek bakalım.

encAuth"Mühürlenmiş veriler için şifrelenmiş AuthData." Buradaki AuthData'mız önceki "tanınmış kimlik doğrulama" dır, ancak evet yine de şifrelememiz gerekiyor. OSAP oturumu kullandığımız için, ADIP veya Yetkilendirme-Veri Ekleme Protokolü izlenerek şifrelenir. Spesifikasyondan: "ADIP, yeni varlıkların oluşturulmasına ve yeni varlık AuthData'nın güvenli bir şekilde eklenmesine izin verir. Yeni AuthData'nın iletimi, bir OSAP oturumunun paylaşılan sırrına dayalı olarak anahtarla şifreleme kullanır." Ek olarak: "Zorunlu XOR şifreleme algoritması için, içerik oluşturucu, OSAP paylaşılan sırrının SHA-1 karmasını ve bir oturum nonce kullanarak bir şifreleme anahtarı oluşturur. Oluşturan XOR, şifreleme anahtarını tek seferlik ped olarak kullanarak yeni AuthData'yı şifreler ve bu şifrelenmiş verileri oluşturma isteğiyle birlikte TPM'ye gönderir. "

Aşağıdaki şema, ADIP'nin nasıl çalıştığını açıklamaktadır:

ADIP

pubAuth"Girişler ve keyHandle için yetkilendirme oturumu özeti." Spesifikasyonun "OIAP ve OSAP Örnekleri için Parametre Açıklamaları" bölüm 1, yukarıdaki TPM_Seal parametre tablosunun nasıl yorumlanacağını açıklar: "HMAC # sütunu, HMAC hesaplamasında kullanılan parametrelerin ayrıntılarını verir. Parametreler 1S, 2S, vb. Birleştirilir ve inParamDigest veya outParamDigest'e karma oluşturuldu, örtük olarak iki yetkilendirme oturumu varsa 1H1 ve muhtemelen 1H2 olarak adlandırılır. İlk oturum için 1H1, 2H1, 3H1 ve 4H1 birleştirilir ve HMAC eklenir. İkinci oturum için 1H2, 2H2, 3H2, ve 4H2 birleştirilir ve HMAC'lanır. " Bu nedenle düz metne, boyutuna, PCR bilgi boyutuna encAuthyukarıdan ve TPM_Seal ordinalinden hash hale getirmemiz gerekecek ve ardından iki nonce ve OSAP kullanarak "devam oturumu" boolean ile HMAC "

Hepsini bir şemada bir araya getirmek:

pubAuth hesaplaması

Verileri bir sistem durumuna kilitlemeden şifrelemek istediğimizden, bu kodda "PCR bilgi boyutunu" sıfıra nasıl ayarladığımıza dikkat edin. Bununla birlikte, gerekirse bir "PCR bilgisi" yapısı sağlamak önemsizdir.

    offset = 0;
    AddUInt16Reversed (cmdBuf, 0x00C2, ref offset); 
    offset = 6;
    AddUInt32Reversed (cmdBuf, 0x00000017, ref offset); // TPM_ORD_SEAL;
    ...
    result = Tbsip_Submit_Command (hContext, 0, 200, pCmd, cmdSize, pRes, & resSize);

Sonunda komutu oluşturup gönderiyoruz.

    byte[] retBuffer = new byte[responseSize - 10];
    Array.Copy (response, 10, retBuffer, 0, retBuffer.Length);
    Tbsip_Context_Close (hContext);
    return retBuffer;

İletişim tutamacımızı kapatmak için Tbsip_Context_Close () işlevini kullanıyoruz.

Yanıtı olduğu gibi döndürüyoruz. İdeal olarak, baytları yeniden tersine çevirmek ve resAuthortadaki adam saldırılarını önlemek için değeri yeniden hesaplayarak doğrulamak istersiniz .


Kafa karıştırıcı olan, Tspi_Data_Bind komutunun olmamasıdır.

Bunun nedeni, Tspi_Data_Bind'in bir TPM komutu değil, bir TSS komutu olmasıdır. Bunun nedeni, sır gerektirmemesidir (yalnızca genel anahtar kullanılır), böylece TPM'yi dahil etmeden yapılabilir. Ancak bu kafa karışıklığına neden oldu ve sır gerektirmeyen komutlar bile artık TPM 2 spesifikasyonuna dahil edildi.

TPM'nin genel anahtarıyla bir anahtarı nasıl şifreleyebilirim?

TPM sürümüne bağlıdır. TPM 1.2 için TPM_CreateWrapKey komutuyla. TPM 2 için TPM2_Create komutuyla.

Bir geliştirici bir anahtarı TPM'ye nasıl kilitler?

TPM'de oluşturun veya sarın ya da mevcut yöntemlerden herhangi birini kullanın.

TPM2_Create, bir HMAC anahtarı belirterek

Kitaptaki metin kafa karıştırıcı. Sen belirtmeyen HMAC anahtarı size istediğinizi belirtin bir HMAC anahtarı .

HMAC anahtarının gizli olmadığı gerçeği mantıklı

Hayır mantıklı değil. Anahtar gizlidir.

... anahtarları bir donanım aygıtında güvende tutarken kullanın ... Mükemmel! Bunu nasıl yapıyorsun!?

TPM'nin her iki sürümü için anahtar oluşturmak veya bunları içe aktarmak için komutlar vardır. TPM 1 için, sarmalanmış anahtarlar oluşturarak bir anahtar hiyerarşisi oluşturabileceğiniz tek bir kök anahtar - SRK - vardı. TPM 2 ile birden çok birincil veya kök anahtarınız olabilir.

TPM'nin şifreleme anahtarları oluşturma ve sırlarını bir donanım sınırı içinde koruma yeteneği var mı? Öyle mi, nasıl?

Yukarıyı görmek.

Mükemmel! Bu tam da istediğim kullanım durumu. Ayrıca Microsoft'un TPM'yi. Nasıl yaparım!?

Muhtemelen sürücünün türüne bağlıdır. SED olmayan sürücüler durumunda, sürücü şifreleme anahtarı büyük olasılıkla bir TPM anahtarıyla sarılır. SED sürücüler söz konusu olduğunda, Yönetici1 şifresi (veya benzeri) TPM ile mühürlenir.

Onay Anahtarı veya EK ... TPM'nin içinde bir yerlerde bir RSA özel anahtarı bulunur. O anahtar orada kilitli - dış dünya tarafından asla görülmeyecek. TPM'nin kendi özel anahtarıyla bir şey imzalamasını istiyorum (yani, özel anahtarıyla şifreleyin).

EK bir imzalama anahtarı değildir - bir şifreleme anahtarıdır. Ancak, genel amaçlı şifreleme anahtarı değil: sadece belli bağlamlarda kullanılabilir .

Ama gerçekten yapmak istediğim şey, bazı verileri "mühürlemek"

Yukarıyı görmek.


2

Dediğinde

HMAC anahtarını belirleme

HMAC anahtarını sağlamak anlamına GELMEZ - "kullanmak istediğiniz HMAC anahtarını işaret edin" anlamına gelir .

TPM'ler, kitapta belirtildiği gibi neredeyse sınırsız sayıda HMAC anahtarı kullanabilir. TPM'ye hangisinin kullanılacağını söylemelisiniz.


Öyleyse, C # veya başka bir dilde kullanılacak HMAC anahtarının nasıl belirleneceğini (işaret edeceğini) gösteren bir kod örneği olabilir mi?
Chad
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.