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 CryptProtectData
API sağlar; bu, kullanımı kolay bir işlevi sarabilir:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Detayları, ProtectBytes
onu 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 ProtectBytes
için, Crypt API
baytları 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, System
anahtar 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 :
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_seal
komutu 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, System
LSA'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 mı ? Ö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 :
Ö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" :
- 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 :
- Microsoft İlkel Sağlayıcı (
MS_PRIMITIVE_PROVIDER
) varsayılanı : Tüm temel öğelerin varsayılan yazılım uygulaması (karma, simetrik şifreleme, dijital imzalar, vb.) - Microsoft Platform Crypto Provider (
MS_PLATFORM_CRYPTO_PROVIDER
): TPM erişimi sağlayan sağlayıcı
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:
- RSA asimetrik şifreleme yapmak istiyorum (TPM kullanarak)
- Microsoft BestCrypt, RSA asimetrik şifrelemeyi destekler
- Microsoft BestCrypt'in bir TPM Sağlayıcısı vardır
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 55publicExponent
: 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 .