WindowsDataProtectionNAILabs,NetworkAssociates,Inc.October2001
Summary:ThisarticlediscusseshowtouseDataProtectionapplicationprogramminginterface(DPAPI)andhowDPAPIoperatesinMicrosoftWindowsXP.(18printedpages)
Contents
IntroductionDPAPIArchitectureUsingDPAPIDPAPISecurityContributorsReferencesIntroduction
StartingwithMicrosoft®Windows®2000,theoperatingsystembegantoprovideadataprotectionapplication-programminginterface(API).ThisDataProtectionAPI(DPAPI)isapairoffunctioncallsthatprovideOS-leveldataprotectionservicestouserandsystemprocesses.ByOS-level,wemeanaservicethatisprovidedbytheoperatingsystemitselfanddoesnotrequireanyadditionallibraries.Bydataprotection,wemeanaservicethatprovidesconfidentialityofdatathroughencryption.SincethedataprotectionispartoftheOS,everyapplicationcannowsecuredatawithoutneedinganyspecificcryptographiccodeotherthanthenecessaryfunctioncallstoDPAPI.ThesecallsaretwosimplefunctionswithvariousoptionstomodifyDPAPIbehavior.Overall,DPAPIisaveryeasy-to-useservicethatwillbenefitdevelopersthatmustprovideprotectionforsensitiveapplicationdata,suchaspasswordsandprivatekeys.DPAPIisapassword-baseddataprotectionservice:itrequiresapasswordtoprovideprotection.Thedrawback,ofcourse,isthatallprotectionprovidedbyDPAPIrestsonthepasswordprovided.ThisisoffsetbyDPAPIusingprovencryptographicroutines,specificallythestrongTriple-DESalgorithm,andstrongkeys,whichwe'llcoverinmoredetaillater.SinceDPAPIisfocusedonprovidingprotectionforusersandrequiresapasswordtoprovidethisprotection,itlogicallyusestheuser'slogonpasswordforprotection.TofamiliarizeyouwithDPAPI,thisarticlewillfirstdiscusshowDPAPIworks,includinginteractionsbetweenapplications,DPAPI,andothersystemcomponents.ItwillalsodetailhowtouseDPAPI,specificallyforuserapplications.Finally,itwilldiscussthesecurityofDPAPI,payingparticularattentiontohowDPAPIgeneratesandusescryptographickeys.WhileDPAPIappearedinWindows2000,thisarticlewillonlydiscusshowtouseDPAPIandhowDPAPIoperatesinWindowsXP.DPAPIArchitecture
ThepublicDPAPIinterfacesarepartofcrypt32.dllandareavailableforanyuserprocessthathasloadedit.ThisDLLispartofCryptoAPI;applicationdeveloperscanassumethatallWindowssystemshavethisDLLavailable.ApplicationseitherpassplaintextdatatoDPAPIandreceiveanopaqueprotecteddatablobback,orpasstheprotecteddatablobtoDPAPIandreceivetheplaintextdataback.Figure1,below,showsthesetwooperations.Figure1.DPAPIisasimpleAPITheprotecteddatablobisanopaquestructure,becauseinadditiontotheencrypteddata,italsocontainsdatatoallowDPAPItounprotectit.Beingopaque,applicationdevelopersdonotneedtoparseorunderstandtheformatatall.AnimportantpointtorememberisthatDPAPImerelyappliescryptographicprotectiontothedata.Itdoesnotstoreanyoftheprotecteddata;thereforeapplicationscallingDPAPImustimplementtheirownstorageoftheprotecteddata.WhenanapplicationcallsoneoftheDPAPIfunctions,thefunctionsmakealocalRPCcalltotheLocalSecurityAuthority(LSA).TheLSAisasystemprocessthatstartsonbootandrunsuntilthecomputerisshutdown.TheselocalRPCcallsnevertraversethenetwork,soalldataremainsonthelocalmachine.TheendpointsoftheseRPCcallsthencallDPAPIprivatefunctionstoprotectorunprotectthedata.ThesefunctionsthencallbackintoCryptoAPI,viacrypt32.dll,fortheactualencryptionordecryptionofthedatainthesecuritycontextoftheLSA.ThefunctionsruninthesecuritycontextoftheLSAsothatsecurityauditscanbegenerated.TheLSAalsocontainssystem-levelfunctionsforusingDPAPI.ThesefunctionsareavailabletoanythreadrunninginsidetheLSAandonlytothosethreads.ThisisbecausethefunctionsprovideadditionaloptionsforLSAthreads,specificallytoallowLSAthreadstoprotectuserdatathatcannotbeunprotectedbynon-LSAthreadsusingDPAPIsuchasuserapplications.KeysandPasswordsinDPAPI
DPAPIisfocusedonprovidingdataprotectionforusers.Sinceitrequiresapasswordtoprovideprotection,thelogicalstepisforDPAPItouseauser'slogonpassword,whichitdoes,inaway.DPAPIactuallyusestheuser'slogoncredential.Inatypicalsystem,inwhichtheuserlogsonwithapassword,thelogoncredentialissimplyahashoftheuser'spassword.Inasysteminwhichtheuserlogsonwithasmartcard,however,thecredentialwouldbedifferent.Tokeepmatterssimple,we'llusethetermsuserpassword,logonpassword,orjustpasswordtorefertothiscredential.Asmalldrawbacktousingthelogonpasswordisthatallapplicationsrunningunderthesameusercanaccessanyprotecteddatathattheyknowabout.Ofcourse,sinceapplicationsmuststoretheirownprotecteddata,gainingaccesstothedatacouldbesomewhatdifficultforotherapplications,butcertainlynotimpossible.Tocounteractthis,DPAPIallowsanapplicationtouseanadditionalsecretwhenprotectingdata.Thisadditionalsecretisthenrequiredtounprotectthedata.Technically,this"secret"shouldbecalledsecondaryentropy.Itissecondary,because,whileitdoesn'tstrengthenthekeyusedtoencryptthedata,itdoesincreasethedifficultyofoneapplication,runningunderthesameuser,tocompromiseanotherapplication'sencryptionkey.Applicationsshouldbecarefulabouthowtheyuseandstorethisentropy.Ifitissimplysavedtoafile,unprotected,thenadversariescouldaccesstheentropyanduseittounprotectanapplication'sdata.AdditionallytheapplicationcanpassinadatastructurethatwillbeusedbyDPAPItoprompttheuser.This"promptstructure"allowstheusertospecifyanadditionalpasswordforthisparticulardata.WediscussthisstructurefurtherintheUsingDPAPIsection.DPAPIinitiallygeneratesastrongkeycalledaMasterKey,whichisprotectedbytheuser'spassword.DPAPIusesastandardcryptographicprocesscalledPassword-BasedKeyDerivation,describedinPKCS#5,togenerateakeyfromthepassword.Thispassword-derivedkeyisthenusedwithTriple-DEStoencrypttheMasterKey,whichisfinallystoredintheuser'sprofiledirectory.TheMasterKey,however,isnotusedexplicitlytoprotectthedata.Instead,asymmetricsessionkeyisgeneratedbasedontheMasterKey,somerandomdata,andanyadditionalentropy,ifanapplicationchoosestosupplyit.Itisthissessionkeythatisusedtoprotectthedata.Thesessionkeyisneverstored.Instead,DPAPIstorestherandomdataitusedtogeneratethekeyintheopaquedatablob.WhenthedatablobispassedbackintoDPAPI,therandomdataisusedtore-derivethekeyandunprotectthedata.Forsecurityreasons,MasterKeyswillexpire,whichmeansthatafteraperiodoftime,thehard-codedvaluebeingthreemonths,anewMasterKeyisgeneratedandprotectedinthesamemanner.ThisexpirationpreventsanattackerfromcompromisingasingleMasterKeyandaccessingallofauser'sprotecteddata.YouareprobablywonderinghowanapplicationcanunprotectdatathatwasprotectedunderaMasterKeythathasexpired,sincethesessionkeyisderivedfromtheMasterKey,right?Welltheanswerinvolvesatwo-stepprocess.First,DPAPIdoesnotdeleteanyexpiredMasterKeys.Insteadtheyarekeptforeverintheuser'sprofiledirectory,protectedbytheuser'spassword.Second,itstorestheGloballyUniqueIdentifier(GUID)oftheMasterKeyusedtoprotectthedataintheopaquedatablobthatisreturnedtoapplications.WhenthedatablobispassedbackintoDPAPI,theMasterKeycorrespondingtotheGUIDisusedtounprotectthedata.TheotherquestionyoumighthaveishowdoesDPAPIaccessMasterKeysafterauserchangeshisorherpassword?Theanswerisagainatwo-stepprocess.First,DPAPIhooksintothepassword-changingmoduleandwhenauser'spasswordischanged,allMasterKeysarere-encryptedunderthenewpassword.Second,thesystemkeepsa"CredentialHistory"fileintheuser'sprofiledirectory.Whenauserchangeshisorherpassword,theoldpasswordisaddedtothetopofthisfileandthenthefileisencryptedbythenewpassword.Ifnecessary,DPAPIwillusethecurrentpasswordtodecryptthe"CredentialHistory"fileandtrytheoldpasswordtodecrypttheMasterKey.Ifthisfails,theoldpasswordisusedtoagaindecryptthe"CredentialHistory"fileandthenextpreviouspasswordisthentried.ThiscontinuesuntiltheMasterKeyissuccessfullydecrypted.KeyBackupandRestorationinDPAPI
Whenacomputerisamemberofadomain,DPAPIhasabackupmechanismtoallowunprotectionofthedata.WhenaMasterKeyisgenerated,DPAPItalkstoaDomainController.DomainControllershaveadomain-widepublic/privatekeypair,associatedsolelywithDPAPI.ThelocalDPAPIclientgetstheDomainControllerpublickeyfromaDomainControllerviaamutuallyauthenticatedandprivacyprotectedRPCcall.TheclientencryptstheMasterKeywiththeDomainControllerpublickey.ItthenstoresthisbackupMasterKeyalongwiththeMasterKeyprotectedbytheuser'spassword.Whileunprotectingdata,ifDPAPIcannotusetheMasterKeyprotectedbytheuser'spassword,itsendsthebackupMasterKeytoaDomainControllerviaamutuallyauthenticatedandprivacyprotectedRPCcall.TheDomainControllerthendecryptstheMasterKeywithitsprivatekeyandsendsitbacktotheclientviathesameprotectedRPCcall.ThisprotectedRPCcallisusedtoensurethatnoonelisteningonthenetworkcangettheMasterKey.Nowyou'reprobablythinkingthatthisbackupworksgreatwithdomainclients,butyou'realsowonderingwhataboutallthehomeuserswhorunstand-aloneorworkgroupsystems.Well,WindowsXPhasanewfeature:thePasswordResetDisk(PRD).AusercancreateaPRDfromtheControlPanelatanytime,anditthenallowstheusertoresettheirpasswordwhentheyforgetit.WhenthepasswordisresetbythePRD,alloftheuser'sMasterKeysarere-encryptedunderthenewpassword.UsingDPAPI
TherearetwosetsofinterfacestoDPAPI,theuserinterfacesandthesysteminterfaces.Thesearediscussedbelow,followedbytwodatastructures,theCRYPTPROTECT_PROMPTSTRUCT
,whichisthe"promptstructure"mentionedearlier,andtheprotecteddatablobthatholdstheprotecteddata.TheuserinterfacescontaintheonlytwofunctionsapplicationdevelopersneedtoknowtouseDPAPI.Theprotectfunction:CryptProtectData()
andtheunprotectfunction:CryptUnprotectData()
.Theonlyrequirementforapplicationstousethesefunctionsistoeitherlinkwithcrypt32.libordynamicallyloadcrypt32.dll.Theprotectfunctiontakesaplaintextdataasinputandreturnsanopaqueprotecteddatablob.Theunprotectfunctiontakesthisopaquedatablobandreturnstheplaintextdata.ThesysteminterfacesarepartoftheLSA.Theseinterfacesaredescribedbelowforcompleteness,buttheycannotbecalledbyauserapplication.TheyexistsothatLSAthreadscanuseDPAPIandspecifytheCRYPTPROTECT_SYSTEM
flagtoprotectdatathatcannotbeunprotectedoutsidetheLSA.UserInterfaces
CryptProtectData
Definition[align=center][/align]CopyCodeBOOLWINAPICryptProtectData(
DATA_BLOB*pDataIn,
LPCWSTRszDataDescr,
DATA_BLOB*pOptionalEntropy,
PVOIDpvReserved,
CRYPTPROTECT_PROMPTSTRUCT*pPromptStruct,
DWORDdwFlags,
DATA_BLOB*pDataOut)
ParameterspDataInPointertoaDATA_BLOB
containingtheplaintextdatatobeprotected.ThecbDatamemberholdsthelengthofthepbDatamember'sbytestringthatcontainsthedatatobeprotected.szDataDescrStringwithareadabledescriptionofthedatatobeencrypted.Thisdescriptionstringisincludedwiththeprotecteddata.ThisparameterisoptionalandcanbeNULL.pOptionalEntropyPointertoaDATA_BLOB
containingadditionalentropyusedtoprotectthedata.ThecbDatamemberholdsthelengthofthepbDatamember'sbytestringthatcontainstheoptionalentropy.TheDATA_BLOB
usedintheprotectioncallmustalsobeusedintheunprotectioncall.Thisistheapplicationspecific"secret"mentionedearlier.ThisparameterisoptionalandcanbeNULL.pvReservedReservedforfutureuseandmustbeNULL.pPromptStructPointertoaCRYPTPROTECT_PROMPTSTRUCT
thatprovidesinformationaboutwhereandwhenpromptsaredisplayedandwhatthecontentofthosepromptsshouldbe.Thisstructureisdefinedbelow,afterthefunctiondefinitions.ThisparameterisoptionalandcanbeNULL.dwFlagsThefollowingtableliststhedefinedflagsvalues:CRYPTPROTECT_LOCAL_MACHINE | Whenthisflagisset,itassociatesthedataprotectedwiththecurrentcomputerinsteadofwithanindividualuser.AnyuseronthecomputeronwhichCryptProtectData() iscalledwiththisflagcanuseCryptUnprotectData() tounprotectthedata.Applicationdevelopersshouldunderstandthatbyusingthisflagno"real"protectionisprovidedbyDPAPI.By"real"wemeanthatanyprocessrunningonthesystemcanunprotectanydataprotectedwiththisflag.Wehighlyrecommendedthatthisflagnotbeusedonworkstationstoprotectuser'sdata.Itdoesmakesense,however,foraserverprocesstousetheflagonaserverwhereuntrustedusersarenotallowedtologon.Italsomakessenseforalocalmachineprocesstousetheflagtoprotectdatatobestoredoffthemachineoronashareddrive. |
CRYPTPROTECT_UI_FORBIDDEN | Thisflagisusedforremotesituationswherepresentingauserinterface(UI)isnotanoption.WhenthisflagissetandaUIisspecifiedforeitherprotectionorunprotection,thecallfailsandGetLastError() returnstheERROR_PASSWORD_RESTRICTION statuscode. |
CRYPTPROTECT_AUDIT | ThisflagcausesDPAPItogenerateanauditwhenthisdataisprotectedorunprotected. |
CRYPTPROTECT_CRED_SYNC | Whenthisflagisused,nodataisactuallyprotected.InsteadallMasterKeysarequeriedfromdisk,whichwillcausere-encryptioninmemory,presumablyunderachangedpassword. |
CRYPTPROTECT_SYSTEM | Causesfailureofthecall. |
pDataOutPointertoaDATA_BLOB
thatreceivestheprotecteddata.ThisbufferisallocatedbyCryptProtectData()
anditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ReturnvaluesIfthefunctionsucceeds,thereturnvalueisTRUE
.Ifthefunctionfails,thereturnvalueisFALSE
.Forextendederrorinformation,callGetLastError()
.ReferenceFormoreinformationandexamplesourcecode,pleaseseeCryptProtectData.CryptUnprotectData
Definition[align=center][/align]CopyCodeBOOLWINAPICryptUnprotectData(DATA_BLOB*pDataIn,LPCWSTR*ppszDataDescr,DATA_BLOB*pOptionalEntropy,PVOIDpvReserved,CRYPTPROTECT_PROMPTSTRUCT*pPromptStruct,DWORDdwFlags,DATA_BLOB*pDataOut)
ParameterspDataInPointertoaDATA_BLOB
containingtheprotecteddata.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainsthedatatobeunprotected.ppszDataDescrPointertoastringwherethereadabledescriptionincludedwiththeprotecteddataisplaced.ThisbufferisallocatedbyCryptUnprotectData()
,anditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ThisparameterisoptionalandcanbeNULL.pOptionalEntropyPointertoaDATA_BLOB
containingadditionalentropyusedwhenthedatawasprotected.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainstheoptionalentropy.Thisistheapplicationspecific"secret"mentionedearlier.ThisparameterisoptionalandcanbeNULL.However,iftheoptionalentropywasusedintheprotectioncall,thatsameentropymustbeusedintheunprotectioncall.pvReservedReservedforfutureuseandmustbeNULL.pPromptStructPointertoaCRYPTPROTECT_PROMPTSTRUCT
thatprovidesinformationaboutwhereandwhenpromptsaredisplayedandwhatthecontentofthosepromptsshouldbe.Thisstructureisdefinedbelow,afterthefunctiondefinitions.Whilethisparameterisoptionalfortheprotectioncall,itisrecommendedthatthecallingapplicationprovideavalidpointerhere;ifapPromptStruct
wasprovidedtotheCryptProtectData()
call,thispointerwillberequired.dwFlagsThefollowingtableliststhedefinedflagsvalues:CRYPTPROTECT_UI_FORBIDDEN | Thisflagisusedforremotesituationswherepresentingauserinterface(UI)isnotanoption.WhenthisflagissetandaUIisspecifiedforeitherprotectionorunprotection,thecallfailsandGetLastError() returnstheERROR_PASSWORD_RESTRICTION statuscode. |
CRYPTPROTECT_VERIFY_PROTECTION | IftheprotecteddatablobwouldbebetterprotectedunderanewcalltoCryptProtectData() andthiscallsucceeds,thenGetLastErrorwillreturnaCRYPT_I_NEW_PROTECTION_REQUIRED statuscode. |
CRYPTPROTECT_SYSTEM | Causesfailureofthecall. |
pDataOutPointertoaDATA_BLOB
thatreceivestheplaintextdata.ThisbufferisallocatedbyCryptUnprotectData()
anditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ReturnvaluesIfthefunctionsucceeds,thereturnvalueisTRUE
.Ifthefunctionfails,thereturnvalueisFALSE
.Forextendederrorinformation,callGetLastError()
.ReferenceFormoreinformationandexamplesourcecode,pleaseseeCryptUnprotectData.SystemInterfaces
InternalProtectFunction
Definition[align=center][/align]CopyCodeBOOLWINAPIInternalProtectFunction(DATA_BLOB*pDataIn,LPCWSTRszDataDescr,DATA_BLOB*pOptionalEntropy,PVOIDpvReserved,CRYPTPROTECT_PROMPTSTRUCT*pPromptStruct,DWORDdwFlags,DATA_BLOB*pDataOut)
ParameterspDataInPointertoaDATA_BLOB
containingtheplaintextdatatobeprotected.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainsthedatatobeprotected.szDataDescrStringwithareadabledescriptionofthedatatobeencrypted.Thisdescriptionstringisincludedwiththeprotecteddata.ThisparameterisoptionalandcanbeNULL.pOptionalEntropyPointertoaDATA_BLOB
containingadditionalentropyusedtoprotectthedata.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainstheoptionalentropy.TheDATA_BLOB
usedintheprotectioncallmustalsobeusedintheunprotectioncall.Thisistheapplicationspecific"secret"mentionedearlier.ThisparameterisoptionalandcanbeNULL.pvReservedReservedforfutureuseandmustbeNULL.pPromptStructPointertoaCRYPTPROTECT_PROMPTSTRUCT
thatprovidesinformationaboutwhereandwhenpromptsaredisplayedandwhatthecontentofthosepromptsshouldbe.Thisstructureisdefinedbelow,afterthefunctiondefinitions.ThisparameterisoptionalandcanbeNULL.dwFlagsThefollowingtableliststhedefinedflagsvalues:CRYPTPROTECT_LOCAL_MACHINE | Whenthisflagisset,itassociatesthedataprotectedwiththecurrentcomputerinsteadofwithanindividualuser.Anyuseronthecomputeronwhichtheinternalprotectfunctioniscalledwiththisflagcanusetheinternalunprotectfunctiontounprotectthedata.Applicationdevelopersshouldunderstandthatbyusingthisflagno"real"protectionisprovidedbyDPAPI.By"real"wemeanthatanyprocessrunningonthesystemcanunprotectanydataprotectedwiththisflag.Wehighlyrecommendedthatthisflagnotbeusedonworkstationstoprotectuser'sdata.Itdoesmakesense,however,foraserverprocesstousetheflagonaserverwhereuntrustedusersarenotallowedtologon.Italsomakessenseforalocalmachineprocesstousetheflagtoprotectdatatobestoredoffthemachineoronashareddrive. |
CRYPTPROTECT_UI_FORBIDDEN | Thisflagisusedforremotesituationswherepresentingauserinterface(UI)isnotanoption.WhenthisflagissetandaUIisspecifiedforeitherprotectionorunprotection,thecallfailsandGetLastError() returnstheERROR_PASSWORD_RESTRICTION statuscode. |
CRYPTPROTECT_AUDIT | ThisflagcausesDPAPItogenerateanauditwhenthisdataisprotectedorunprotected. |
CRYPTPROTECT_CRED_SYNC | Whenthisflagisused,nodataisactuallyprotected.InsteadallMasterKeysarequeriedfromdisk,whichwillcausere-encryptioninmemory,presumablyunderachangedpassword. |
CRYPTPROTECT_SYSTEM | Dataprotectedwiththisflagsetcanonlybeunprotectedwiththisflagset. |
pDataOutPointertoaDATA_BLOB
thatreceivestheprotecteddata.ThisbufferisallocatedbytheinternalprotectfunctionanditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ReturnvaluesIfthefunctionsucceeds,thereturnvalueisTRUE
.Ifthefunctionfails,thereturnvalueisFALSE
.Forextendederrorinformation,callGetLastError()
.InternalUnprotectFunction
Definition[align=center][/align]CopyCodeBOOLWINAPIInternalUnprotectFunction(DATA_BLOB*pDataIn,LPCWSTR*ppszDataDescr,DATA_BLOB*pOptionalEntropy,PVOIDpvReserved,CRYPTPROTECT_PROMPTSTRUCT*pPromptStruct,DWORDdwFlags,DATA_BLOB*pDataOut)
ParameterspDataInPointertoaDATA_BLOB
containingtheprotecteddata.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainsthedatatobeunprotected.ppszDataDescrPointertoastringwherethereadabledescriptionincludedwiththeprotecteddataisplaced.ThisbufferisallocatedbytheinternalunprotectfunctionanditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ThisparameterisoptionalandcanbeNULL.pOptionalEntropyPointertoaDATA_BLOB
containingadditionalentropyusedwhenthedatawasprotected.ThecbData
memberholdsthelengthofthepbData
member'sbytestringthatcontainstheoptionalentropy.Thisistheapplicationspecific"secret"mentionedearlier.ThisparameterisoptionalandcanbeNULL.However,iftheoptionalentropywasusedintheprotectioncall,thatsameentropymustbeusedintheunprotectioncall.pvReservedReservedforfutureuseandmustbeNULL.pPromptStructPointertoaCRYPTPROTECT_PROMPTSTRUCT
thatprovidesinformationaboutwhereandwhenpromptsaredisplayedandwhatthecontentofthosepromptsshouldbe.Thisstructureisdefinedbelow,afterthefunctiondefinitions.Whilethisparameterisoptionalfortheprotectioncall,itisrecommendedthatthecallingapplicationprovideavalidpointerhere,becauseifapPromptStruct
wasprovidedtotheinternalprotectfunction,thispointerwillberequired.dwFlagsThefollowingtableliststhedefinedflagsvalues:CRYPTPROTECT_UI_FORBIDDEN | Thisflagisusedforremotesituationswherepresentingauserinterface(UI)isnotanoption.WhenthisflagissetandaUIisspecifiedforeitherprotectionorunprotection,thecallfailsandGetLastError() returnstheERROR_PASSWORD_RESTRICTION statuscode. |
CRYPTPROTECT_VERIFY_PROTECTION | Iftheprotecteddatablobwouldbebetterprotectedunderanewcalltotheinternalprotectfunctionandthiscallsucceeds,thenGetLastErrorwillreturnaCRYPT_I_NEW_PROTECTION_REQUIRED statuscode. |
CRYPTPROTECT_SYSTEM | Ifdatawasprotectedwiththisflagset,thenthisflagmustbesettounprotectthedata. |
pDataOutPointertoaDATA_BLOB
thatreceivestheplaintextdata.ThisbufferisallocatedbytheinternalunprotectfunctionanditistheresponsibilityofthecallingapplicationtofreeitwithacalltoLocalFree()
.ReturnvaluesIfthefunctionsucceeds,thereturnvalueisTRUE
.Ifthefunctionfails,thereturnvalueisFALSE
.Forextendederrorinformation,adevelopershouldcallGetLastError()
.DataStructures
CRYPTPROTECT_PROMPTSTRUCT
TheCRYPTPROTECT_PROMPTSTRUCTisastructureprovidingapromptthatwillbedisplayedwhendataisprotectedorunprotected.Thisisthe"promptstructure"discussedearlierintheDPAPIArchitecturesection.Figure2.InitialdialogFigure2,above,showsthedialogwhichfirstaskstheusertospecifyeitherMediumorHighsecurityforthedata,withMediumbeingthedefaultselected.IfthesecuritylevelissettoHigh,thedialogthenpromptstheuserforanadditionalpassword,and,iftheapplicationhasn'tspecifiedone,adescriptionforthedata.ThisdialogisshownbelowinFigure3.Figure3.PasswordanddescriptiondialogWhencallingCryptUnprotectData()
,werecommendthatanapplicationalwayspassinapointertoapromptstruct.Thisisbecauseifthedatawasprotectedwithapromptstruct,DPAPIwillrequireapromptstructtounprotectthedata,andthefunctionwillfailifoneisnotpassedin.Definition[align=center][/align]CopyCodetypedefstruct_CRYPTPROTECT_PROMPTSTRUCT{DWORDcbSize;DWORDdwPromptFlags;HWNDhwndApp;LPCWSTRszPrompt;}CRYPTPROTECT_PROMPTSTRUCT,*PCRYPTPROTECT_PROMTPSTRUCT;
ElementscbSizeSizeofstructureinbytes.dwPromptFlagsWhentheCRYPTPROTECT_PROMPTSTRUCT
ispassedtoCryptProtectData()
ortheinternalprotectfunction,thetablebelowliststhedefinedflagvalues.WhentheCRYPTPROTECT_PROMPTSTRUCT
ispassedtoCryptUnprotectData()
ortheinternalunprotectfunction,noflagvaluesaredefined.CRYPTPROTECT_PROMPT_ON_PROTECT | Promptonprotectandunprotect. |
CRYPTPROTECT_PROMPT_ON_UNPROTECT | Promptonprotectandunprotect. |
CRYPTPROTECT_STRONG | Setthedefaultusersecurityleveltostrong. |
hwndAppWindowhandletoparentwindow.szPromptStringcontainingthetextfortheprompt.ReferenceFormoreinformationandexamplesourcecode,pleaseseeCRYPTPROTECT_PROMPTSTRUCT.Protecteddatablob
Aswesaidbefore,DPAPIdoesnotactuallystoreanydata.Itsimplyprotectsdata.Itistheapplicationsresponsibilitytostoretheprotecteddata.CryptProtectData()
returnsanopaquedatablob,anditissufficientforapplicationstostorethisblobinsomeway,theydonothavetoparsetheinternalsofitforanyreason.ToprotectagainsttamperingoftheDPAPIdataortheencrypteddata,theentireblobishashedwithaHashedMessageAuthenticationCode(HMAC),inthiscaseSHA-1.Forreferencepurposes,thesizeofthedatablobis708bitsplusthelengthofthedescriptiontext,encrypteddata,andMAC.Inaddition,ifDPAPIhastoprovideasaltvaluetotheCryptographicServiceProvider(CSP),thestructwillbealittlelargerinsize,butformostCSPs,thissaltisnotneeded.DPAPISecurity
DPAPIprovidesanessentialdataprotectioncapabilitythatensurestheconfidentialityofprotecteddatawhileallowingrecoveryoftheunderlyingdataintheeventoflostorchangedpasswords.Thepassword-basedprotectionprovidedbyDPAPIisexcellentforanumberofreasons.Itusesprovencryptographicroutines,suchasthestrongTriple-DESalgorithminCBCmode,thestrongSHA-1algorithm,andthePBKDF2password-basedkeyderivationroutine.Itusesprovencryptographicconstructstoprotectdata.Allcriticaldataiscryptographicallyintegrityprotected,andsecretdataiswrappedusingstandardmethods.Ituseslargesecretsizestogreatlyreducethepossibilityofbrute-forceattackstocompromisethesecrets.ItusesPBKDF2with4000iterationstoincreasetheworkfactorofanadversarytryingtocompromisethepassword.ItsanitychecksMasterKeyexpirationdates.ItprotectsallrequirednetworkcommunicationwithDomainControllersbyusingmutuallyauthenticatedandprivacyprotectedRPCchannels.Itminimizestheriskofexposinganysecrets,byneverwritingthemtodiskandminimizingtheirexposureinswappableRAM.ItrequiresAdministratorprivilegestomakeanymodificationstotheDPAPIparametersintheregistry.ItusesWindowsFileProtectiontohelpprotectallcriticalDLLsfromonlinechangesevenbyprocesseswithAdministratorprivileges.DPAPI,however,isnot100percentfoolproof.ThePasswordResetDiskcanbestolen,allowinganattackertoresetauser'spassword.DPAPIisalsosusceptible,asanypassword-basedsystemis,tosocialengineeringattacks,inwhichanadversarytricksauserintodisclosingapasswordortricksadomainadministratorintoresettingauser'spassword.Finally,whiletheCRYPTPROTECT_LOCAL_MACHINEflagcanprovideexcellentprotectionincertaincircumstances,itispossibletouseitinaninappropriatemannersuchthatnorealprotectionisprovided.OnefeaturewedonotdiscussisthatDPAPIcanbeconfiguredtooperatewithaWindows2000serverinalegacymode.Inthismode,itispossibletobackuptheMasterKeysunderalocalLSAsecret.TheMasterKeys,alongwiththeLSA,andanyprotecteddatacanthenbestolenbyanadversaryanddecryptedatwill.Forthistooccur,however,anAdministratormustmodifytheregistrytoconfigureDPAPIforthislegacymode.Othervulnerabilitiesalsorequiregreaterattackereffortandreducedpayoff.TheseincludeattackssuchasinsertingarogueCSPintotheoperatingsystemorforcinghibernationatacriticalmomentsothatin-usesecretsinRAMgetwrittentothehibernationfile.Overall,DPAPIprovidesverygoodsecurity,consideringtheprotectionisbasedonauser'spassword.BelowwediscussinmoredetailthesecurityofDPAPI,specificallyhowitgeneratesandusescryptographickeys.KeyRelationships
Figure4,below,showshowallthedifferentkeysoperatetogethertoallowDPAPItoprovidedataprotection.Thekeysarediscussedfurtherinthefollowingsections.TheboldcircleindicatesthecenteroftheDPAPIkeyrelationships:theuserpassword.Onstandalonesystems,therecoverykeyprotectsthepasswordtoallowuserstoresettheirpasswordswiththePRD.TheuserpasswordisusedtoderivetheMasterKeyEncryptionKey,whichisusedtoprotecttheMasterKey.Finally,aderivationofthispassword,theusercredential,isstoredinthe"CredentialHistory"file,whichallowsDPAPItoaccessMasterKeysprotectedunderoldpasswords.Ondomainworkstations,aDomainControllerpublickeyalsoprotectstheMasterKey.ThisallowsDPAPItoaccessaDomainControllerandrestoretheMasterKey,ifitcannotusetheMasterKeyEncryptionKey.Finally,theMasterKeyisusedtoderivetheSymmetricSessionKey,whichthenprotectstheapplicationdata.Figure4.KeyrelationshipsMasterKey
WesaidearlierthatDPAPIgeneratesastrongkeycalledtheMasterKey.CallingtheMasterKeyakeyisn'treallycorrect,asitisneverusedinanyexplicitencryptionordecryptionfunctions.TheMasterKeyismoreaccuratelyastrongsecret:strongbecauseitis512bitsofrandomdata,andsecretbecauseitisused,withsomeadditionaldata,togenerateanactualsymmetricsessionkey.Thissecret,however,needstobekeptsecurefromeveryonebuttheintendeduser.Toprotectthissecret,DPAPIusesthePassword-BasedKeyDerivationFunction,PBKDF2,describedinPKCS#5.First,DPAPItakestheuser'spasswordandpassesitthroughSHA-1togetapasswordhash.Thisisthelogoncredentialmentionedearlier.Next,thepasswordhashisprovidedtothePBKDF2function,alongwithsixteenrandombytesforasaltandaniterationcount.ThePBKDF2functioncallsanadditionalfunctionanumberoftimes,specifiedbytheiterationcount,toderiveakeyfromthegivendata.DPAPIusesSHA-1forthatunderlyingfunction.Thedefaultiterationcountis4000,whichincreasestheworkloadrequiredtobrute-forcecompromisethepasswordbyafactorof4000,withoutcreatingundueperformancerestrictionsinnormaloperations.ThereisaregistryvalueMasterKeyIterationCount
storedintheHKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Protect\Providers\GUID
keythatallowsasystemadministratortoincreasethisiterationcount.Itcannot,however,bedecreasedbelow4000.TopreventtamperingoftheMasterKey,itishashedwithanHMAC.DPAPIagainusesSHA-1fortheHMACandtheuser'spasswordtoderivetheHMACkey.Thepassword-derivedencryptionkey,fromabove,isthenusedwithTriple-DEStoencrypttheMasterKeyandtheHMACoftheMasterKey.Thesaltanditerationcountarebothnon-secretvalues,andthereforearestoredalongwiththeencryptedMasterKey,butarenotencrypted.ThisallowsDPAPItoeasilydecrypttheMasterKey,giventheuser'spassword.Atthispoint,ifthecomputerisadomainmember,thebackupsteps,outlinedintheKeyBackupandRestorationinDPAPIsection,areperformed.Finally,theencryptedMasterKeyandHMAC,salt,iterationcount,andbackupMasterKeyareallstoredinaMasterKeyfile,whichresidesintheuser'sprofiledirectory.SessionKey
Thesessionkeyistherealsymmetrickeythatisusedforencryptinganddecryptingtheapplicationdata.DPAPIusesasimpleprocesstoderivethesessionkey.First,16bytesofrandomdataaregeneratedandthenhashed,viaSHA-1,withtheMasterKey.Thishashisthenappendedwiththeoptionalentropyandoptionaluserpassword,mentionedearlier,viaCryptHashData()
,aCryptoAPIcall.TheresultisthenpassedtoCryptDeriveKey()
,anotherCryptoAPIcall,whichderivesandreturnsthesessionkey.Aswementionedearlier,thesessionkeyisneverstoredanywhere;itisderived,used,andthenremovedfrommemory.SothatDPAPIcanunprotectthedata,thegeneratedrandombytesarestoredintheprotecteddatablob.Whiletheserandombytesarestoredunprotected,sincetheMasterKeyisprotected,theyareauthenticatedwithanHMACtopreventtampering.RecoveryKey
TherecoverykeyisgeneratedwhenauserchoosestocreateaPasswordResetDisk(PRD)fromtheUsersControlPanel.First,DPAPIgeneratesa2048bitRSApublic/privatekeypair,whichistherecoverykey.Thecurrentpasswordisthenencryptedwiththepublickeyandstoredintheuser'sprofile,whiletheprivatekeyisstoredtothePRD,whichcanactuallybeanyremovablemedia,andthenremovedfrommemory.TheprivatekeyisonlystoredonthePRD,andnowhereelse,soitisimportantforausertokeepthePRDinasafeplace.Ifusersenterthewrongpassword,WindowsasksthemwhethertheywouldliketousethePRDandresetthepassword.Iftheychooseto,awizardrunsthatpromptsforthenewpasswordandusestheprivatekeyonthePRDtodecrypttheoldpasswordandmakethechange.Contributors
ThecontributorsofthisdocumentareWesleyGriffin,MichaelHeyman,DavidBalenson,andDavidCarman,membersoftheCryptographicTechnologiesGroupinNAILabs,theSecurityResearchDivisionofNetworkAssociates,Inc.NAILabsisamulti-disciplineresearchorganizationwithworld-renownedexpertiseintheareasofnetworksecurity,appliedcryptographictechnologies,secureexecutionenvironments,securityinfrastructure,adaptivenetworkdefenses,distributedsystemssecurity,andinformationassurance.NAILabswouldliketoacknowledgethehelpofPeterBrundrett,MikeLai,DavidHubbard,JohnBanes,ScottField,GeorgeMasters,andCraigDelthony,allatMicrosoft,forprovidinginformationonDPAPI.WewouldalsoliketothankDaveThompsonandDougBayerforcontributingMicrosoftresources.References
CryptProtectData.CryptUnprotectData.CRYPTPROTECT_PROMPTSTRUCT.PKCS#5v2.0:Password-BasedCryptographyStandard.RSALaboratories.March25,1999.http://www.cnblogs.com/jjkv3/admin/ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.doc.RFC-2404:TheUseofHMAC-SHA-1-96withinESPandAH.C.Madson,R.Glenn.November1998.http://www.ietf.org/rfc/rfc2404.txt.