Che cos'è lo stato di visualizzazione?
Lo stato di visualizzazione è costituito da informazioni di andata e ritorno tra pagine WebForms (.aspx) in un'applicazione ASP.NET. Il markup HTML per il campo __VIEWSTATE è simile al seguente:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
Un esempio di elemento che potrebbe essere archiviato nel campo __VIEWSTATE è il testo di un controllo Button. Se un utente fa clic sul pulsante, il gestore dell'evento Button_Click sarà in grado di estrarre il testo del pulsante dal campo dello stato di visualizzazione. Per una panoramica molto più dettagliata dello stato di visualizzazione ASP.NET, vedere l'argomento Panoramica dello stato di visualizzazione di ASP.NET sul sito Web di Microsoft Developer Network (MSDN).
Poiché il campo __VIEWSTATE contiene informazioni importanti che vengono utilizzate per ricostruire la pagina al postback, assicurarsi che un utente malintenzionato non possa manometterlo. Se un utente malintenzionato inviava un payload di __VIEWSTATE dannoso, l'utente malintenzionato potrebbe indurre l'applicazione a eseguire un'azione che altrimenti non avrebbe eseguito.
Per impedire questo tipo di attacco di manomissione, il campo __VIEWSTATE è protetto da un codice MAC (Message Authentication Code). ASP.NET convalida il percorso MAC inviato insieme al payload __VIEWSTATE quando si verifica un postback. La chiave utilizzata per calcolare l'indirizzo MAC è specificata nell'elemento dell'applicazione nel file Web.config. Poiché l'utente malintenzionato non è in grado di indovinare il contenuto dell'elemento <machineKey> , l'utente malintenzionato non può fornire un indirizzo MAC valido se tenta di manomettere il payload __VIEWSTATE. ASP.NET rileverà che non è stato fornito un MAC valido e ASP.NET rifiuterà la richiesta dannosa.
Quali sono le cause degli errori di convalida MAC?
Un errore di convalida MAC sarà simile all'esempio seguente:
Nota
Errore del server nell'applicazione '/'.
Convalida dell'indirizzo MAC dello stato di visualizzazione non riuscita. Se l'applicazione è ospitata da una Web farm o da un cluster, verificare che <la configurazione di machineKey> specifichi lo stesso algoritmo di convalida. AutoGenerate non può essere utilizzato in un cluster.
Descrizione: si è verificata un'eccezione non gestita durante l'esecuzione della richiesta Web corrente. Esamina l'analisi dello stack per altre informazioni sull'errore e su dove ha avuto origine nel codice.
Dettagli eccezione: System.Web.HttpException: convalida dell'indirizzo MAC dello stato di visualizzazione non riuscita. Se l'applicazione è ospitata da una Web farm o da un cluster, verificare che <la configurazione di machineKey> specifichi lo stesso algoritmo di validationKey e di convalida. AutoGenerate non può essere utilizzato in un cluster.
Errore di origine: [Nessuna riga di origine rilevante]
File sorgente: ... Linea: 0
Traccia dello stack:
[ViewStateException: stato di visualizzazione non valido.
IP client: ::1
Porta: 40653
Referente: http://localhost:40643/MyPage.aspx
Percorso: /MyPage.aspx
User-Agent: Mozilla/5.0 (compatibile; MSIE 10.0; Windows NT 6.2; WOW64; Tridente/6.0)
ViewState: ...]
[HttpException (0x80004005): Convalida dell'indirizzo MAC dello stato di visualizzazione non riuscita. Se l'applicazione è ospitata da una Web farm o da un cluster, verificare che <la configurazione di machineKey> specifichi lo stesso algoritmo di validationKey e di convalida. AutoGenerate non può essere utilizzato in un cluster.
Vedi http://go.microsoft.com/fwlink/?LinkID=314055 per ulteriori informazioni.]
System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) +190
System.Web.UI.ViewStateException.ThrowMacValidationError(Exception inner, String persistedState) +46
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString, Purpose purpose) +861
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter2. Deserialize(String serializedState, Purpose purpose) +51
System.Web.UI.Util.DeserializeWithAssert(formatter IStateFormatter2, String serializedState, purpose purpose) +67
System.Web.UI.HiddenFieldPageStatePersister.Load() +444
System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +368
System.Web.UI.Page.LoadAllState() +109
System.Web.UI.Page.ProcessRequestMain(booleano includeStagesBeforeAsyncPoint, booleano includeStagesAfterAsyncPoint) +7959
System.Web.UI.Page.ProcessRequest(booleano includeStagesBeforeAsyncPoint, booleano includeStagesAfterAsyncPoint) +429
System.Web.UI.Page.ProcessRequest() +125
System.Web.UI.Page.ProcessRequestWithNoAssert(contesto HttpContext) +48
System.Web.UI.Page.ProcessRequest(contesto HttpContext) +234
ASP.mypage_aspx. ProcessRequest(HttpContext context) in ... :0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +1300
System.Web.HttpApplication.ExecuteStep(passaggio IExecutionStep, booleano& completedSynchronously) +140
Causa 1: l'applicazione Web è in esecuzione in una farm (ambiente multiserver)
ASP.NET genera automaticamente una chiave di crittografia per ogni applicazione e archivia la chiave nell'hive del Registro di sistema HKCU. Questa chiave generata automaticamente viene usata se non è presente alcun elemento machineKey> esplicito <nella configurazione dell'applicazione. Tuttavia, poiché questa chiave generata automaticamente è locale nel computer che ha creato la chiave, questo scenario causa un problema per le applicazioni eseguite in una farm. Ogni server della farm genererà la propria chiave locale e nessuno dei server della farm sarà d'accordo sulla chiave da utilizzare. Il risultato è che, se un server genera un payload __VIEWSTATE utilizzato da un server diverso, il consumer riscontrerà un errore di convalida MAC.
Risoluzione 1a: creare un elemento machineKey> esplicito <
Aggiungendo un elemento machineKey> esplicito <al file di Web.config dell'applicazione, lo sviluppatore ASP.NET dice di non usare la chiave di crittografia generata automaticamente. Per istruzioni su come generare un elemento machineKey,> vedere l'Appendice<A. Dopo aver aggiunto questo elemento al file Web.config, ridistribuire l'applicazione in ogni server della farm.
Nota Alcuni servizi di hosting Web, ad esempio i siti Web di Microsoft Azure, consentono di sincronizzare la chiave generata automaticamente da ogni applicazione nei server back-end. Ciò consente alle applicazioni che non hanno specificato un elemento machineKey> esplicito <di continuare a lavorare in questi ambienti, anche se l'applicazione è in esecuzione in una farm. Se l'applicazione è in esecuzione su un servizio di hosting di terze parti, contattare il provider di hosting per determinare se questa situazione si applica al proprio caso.
Soluzione 1b: abilitare l'affinità nel servizio di bilanciamento del carico
Se i siti operano dietro un servizio di bilanciamento del carico, è possibile abilitare l'affinità tra server per risolvere temporaneamente il problema. In questo modo si garantisce che un determinato client interagisca con un solo server fisico dietro il servizio di bilanciamento del carico, in modo che tutti i payload di crittografia vengano generati e utilizzati dallo stesso server.
Questa non dovrebbe essere considerata una soluzione a lungo termine al problema. Anche quando l'affinità tra server è abilitata, la maggior parte dei servizi di bilanciamento del carico reindirizza il client a un server fisico diverso se il server originale a cui sono stati applicati i servizi di bilanciamento del carico è offline. In questo modo il nuovo server rifiuta i payload crittografici (ad esempio __VIEWSTATE, ticket di autenticazione basata su form, token anti-falsificazione MVC e altri servizi) attualmente disponibili nel client.
L'uso di un elemento machineKey> esplicito <e la ridistribuzione dell'applicazione devono essere preferiti rispetto all'abilitazione dell'affinità server.
Causa 2: il processo di lavoro utilizza l'identità del pool di applicazioni IIS 7.0
Internet Information Services (IIS) 7.0 (Windows Vista Windows Server 2008) ha introdotto l'identità del pool di applicazioni, un nuovo meccanismo di isolamento che consente di fornire una maggiore protezione per i server che eseguono applicazioni ASP.NET. Tuttavia, i siti in esecuzione con l'identità del pool di applicazioni non hanno accesso al Registro di sistema HKCU. Questa è la posizione in cui il runtime ASP.NET archivia le chiavi machineKey> generate <automaticamente. Il risultato è che non ASP.NET possibile mantenere la chiave generata automaticamente quando il pool di applicazioni viene reimpostato. Pertanto, ogni volta che w3wp.exe viene reimpostata, viene generata una nuova chiave temporanea.
Nota: questo problema non è presente in IIS 7.5 (Windows 7, Windows Server 2008 R2) e versioni successive. In queste versioni di IIS, ASP.NET può mantenere le chiavi generate automaticamente in un percorso diverso che sopravvive alle reimpostazioni del pool di applicazioni.
Soluzione 2a: utilizzare l'utilità aspnet_regiis
ASP.NET installazioni contengono un'utilità, aspnet_regiis.exe. Questa utilità consente ASP.NET interfaccia con IIS per eseguire le configurazioni necessarie per l'esecuzione di un'applicazione gestita. Una di queste configurazioni crea le chiavi necessarie nell'hive del Registro di sistema per consentire la persistenza delle chiavi macchina generate automaticamente.
Prima di tutto, è necessario determinare quale pool di applicazioni usa il sito. Questo può essere determinato utilizzando l'utilità inetmgr inclusa in IIS. Selezionare il sito nella struttura ad albero a sinistra, fare clic con il pulsante destro del mouse su Gestisci sito Web,quindi fare clic su Impostazioni avanzate. Nella finestra di dialogo visualizzata verrà visualizzato il nome del pool di applicazioni.
Per eseguire lo scaffolding delle chiavi del Registro di sistema appropriate per un pool di applicazioni ASP.NET 4.0, attenersi alla seguente procedura:
Aprire un prompt dei comandi amministrativo.
Individuare la directory appropriata, a seconda che il pool di applicazioni sia a 32 bit o a 64 bit:
- Pool di applicazioni a 32 bit: cd /d %Windir%\Microsoft.NET\Framework\v4.0.30319
- Pool di applicazioni a 64 bit: cd /d %Windir%\Microsoft.NET\Framework64\v4.0.30319
Passare alla directory, digitare il comando seguente e premere INVIO:
aspnet_regiis -ga "IIS APPPOOL\app-pool-name"
Se il pool di applicazioni è un pool di applicazioni ASP.NET 2.0 o 3.5, seguire questa procedura:
Aprire un prompt dei comandi amministrativo.
Individuare la directory appropriata, a seconda che il pool di applicazioni sia a 32 bit o a 64 bit:
- Pool di applicazioni a 32 bit: cd /d %Windir%\Microsoft.NET\Framework\v2.0.50727
- Pool di applicazioni a 64 bit: cd /d %Windir%\Microsoft.NET\Framework64\v2.0.50727
Passare alla directory, digitare il comando seguente e premere INVIO:
aspnet_regiis -ga "IIS APPPOOL\app-pool-name"
Ad esempio, se il pool di applicazioni è denominato My App Pool (come nell'immagine precedente), eseguire il comando seguente:
aspnet_regiis -ga "IIS APPPOOL\My App Pool"Nota: potrebbe essere necessario che i servizi di sistema APPHOSTSVC e WAS siano in esecuzione affinché l'utilità aspnet_regiis risolva i nomi APPPOOL\* di IIS in modo appropriato.
Risoluzione 2b: creare un elemento machineKey> esplicito <
Aggiungendo un elemento machineKey> esplicito <al file di Web.config dell'applicazione, lo sviluppatore ASP.NET dice di non usare la chiave di crittografia generata automaticamente. Per istruzioni su come generare un elemento machineKey,> vedere l'Appendice<A.
Causa 3: il pool di applicazioni è configurato utilizzando LoadUserProfile=false
Se il pool di applicazioni è in esecuzione con un'identità personalizzata, è possibile che IIS non abbia caricato il profilo utente per l'identità. Ciò ha l'effetto collaterale di rendere il Registro di sistema HKCU non disponibile per ASP.NET di mantenere il machineKey> generato <automaticamente. Di conseguenza, verrà creata una nuova chiave generata automaticamente ogni volta che l'applicazione viene riavviata. Per altre informazioni, vedere la sezione Profilo utente sul sito Web di Microsoft.
Soluzione 3a: utilizzare l'utilità aspnet_regiis
Le istruzioni per questo sono le stesse della risoluzione 2a. Per altre informazioni, vedere questa sezione.
Risoluzione 3b: usare un codice machineKey esplicito <>
Aggiungendo un elemento machineKey> esplicito <al file di Web.config dell'applicazione, lo sviluppatore ASP.NET dice di non usare la chiave di crittografia generata automaticamente. Per istruzioni su come generare un elemento machineKey,> vedere l'Appendice<A.
Soluzione 3c: effettuare manualmente il provisioning delle chiavi del Registro di sistema HKCU necessarie
Se non è possibile eseguire l'utilità aspnet_regiis, è possibile utilizzare uno script Windows PowerShell per eseguire il provisioning delle chiavi del Registro di sistema appropriate in HKCU. Per ulteriori informazioni, vedere l'Appendice B .
Risoluzione 3d: Impostare LoadUserProfile=true per questo pool di applicazioni
È anche possibile abilitare il caricamento del profilo utente all'interno di questo pool di applicazioni. In questo modo l'hive del Registro di sistema HKCU, la cartella temporanea e altre posizioni di archiviazione specifiche dell'utente sono disponibili per l'applicazione. Ciò potrebbe tuttavia causare un aumento dell'utilizzo del disco o della memoria per il processo di lavoro. Per altre informazioni su come abilitare questa impostazione, vedere l'elemento .
Causa 4: la proprietà Page.ViewStateUserKey contiene un valore non corretto
Gli sviluppatori di software possono decidere di usare la proprietà Page.ViewStateUserKey per aggiungere la protezione dalla contraffazione delle richieste tra siti al campo __VIEWSTATE. Se si utilizza la proprietà Page.ViewStateUserKey, in genere viene impostata su un valore come il nome utente dell'utente corrente o l'identificatore di sessione dell'utente. I modelli di progetto per le applicazioni WebForms in Microsoft Visual Studio 2012 e versioni successive contengono esempi che utilizzano questa proprietà. Per ulteriori informazioni, vedere l'argomento relativo alla proprietà Page.ViewStateUserKey nel sito Web Microsoft Developer Network (MSDN).
Se viene specificata la proprietà ViewStateUserKey, il relativo valore viene incorporato in __VIEWSTATE in fase di generazione. Quando viene utilizzato il campo __VIEWSTATE, il server controlla la proprietà ViewStateUserKey della pagina corrente e la convalida in base al valore utilizzato per generare il campo __VIEWSTATE. Se i valori non corrispondono, la richiesta viene rifiutata in quanto potenzialmente dannosa.
Un esempio di errore correlato a ViewStateUserKey è un client con due schede aperte nel browser. Il client viene connesso come utente A e nella prima scheda viene eseguito il rendering di una pagina con un __VIEWSTATE la cui proprietà ViewStateUserKey contiene "Utente A". Nella seconda scheda il client si disconnette e quindi accede nuovamente come utente B. Il cliente torna alla prima scheda e invia il modulo. La proprietà ViewStateUserKey potrebbe contenere "Utente B" (perché questo è ciò che dice il cookie di autenticazione del client). Tuttavia, il campo __VIEWSTATE inviato dal client contiene "Utente A". Questo mancata corrispondenza causa l'errore.
Soluzione 4a: verificare che ViewStateUserKey sia impostato correttamente
Se l'applicazione usa la proprietà ViewStateUserKey, verificare che il valore della proprietà sia lo stesso sia quando viene generato lo stato di visualizzazione sia quando viene utilizzato. Se si utilizza il nome utente dell'utente attualmente connesso, verificare che l'utente sia ancora connesso e che l'identità dell'utente non sia cambiata al momento del postback. Se si usa l'identificatore di sessione dell'utente corrente, verificare che la sessione non sia scaduta.
Se si esegue in un ambiente farm, verificare che gli <elementi machineKey> corrispondano. Vedere l'Appendice A per istruzioni su come generare questi elementi.
Appendice A: Come generare un <elemento machineKey>
Nota
Avviso di sicurezza
Ci sono molti siti web che genereranno un <elemento machineKey> per te con un clic di un pulsante. Non usare mai un <elemento machineKey> ottenuto da uno di questi siti. È impossibile sapere se queste chiavi sono state create in modo sicuro o se vengono registrate in un database segreto. È consigliabile usare <sempre e solo elementi di configurazione machineKey> creati dall'utente.
Per generare autonomamente un <elemento machineKey>, è possibile usare lo script di Windows PowerShell seguente:
# Generates a <machineKey> element that can be copied + pasted into a Web.config file.
function Generate-MachineKey {
[CmdletBinding()]
param (
[ValidateSet("AES", "DES", "3DES")]
[string]$decryptionAlgorithm = 'AES',
[ValidateSet("MD5", "SHA1", "HMACSHA256", "HMACSHA384", "HMACSHA512")]
[string]$validationAlgorithm = 'HMACSHA256'
)
process {
function BinaryToHex {
[CmdLetBinding()]
param($bytes)
process {
$builder = new-object System.Text.StringBuilder
foreach ($b in $bytes) {
$builder = $builder.AppendFormat([System.Globalization.CultureInfo]::InvariantCulture, "{0:X2}", $b)
}
$builder
}
}
switch ($decryptionAlgorithm) {
"AES" { $decryptionObject = new-object System.Security.Cryptography.AesCryptoServiceProvider }
"DES" { $decryptionObject = new-object System.Security.Cryptography.DESCryptoServiceProvider }
"3DES" { $decryptionObject = new-object System.Security.Cryptography.TripleDESCryptoServiceProvider }
}
$decryptionObject.GenerateKey()
$decryptionKey = BinaryToHex($decryptionObject.Key)
$decryptionObject.Dispose()
switch ($validationAlgorithm) {
"MD5" { $validationObject = new-object System.Security.Cryptography.HMACMD5 }
"SHA1" { $validationObject = new-object System.Security.Cryptography.HMACSHA1 }
"HMACSHA256" { $validationObject = new-object System.Security.Cryptography.HMACSHA256 }
"HMACSHA385" { $validationObject = new-object System.Security.Cryptography.HMACSHA384 }
"HMACSHA512" { $validationObject = new-object System.Security.Cryptography.HMACSHA512 }
}
$validationKey = BinaryToHex($validationObject.Key)
$validationObject.Dispose()
[string]::Format([System.Globalization.CultureInfo]::InvariantCulture,
"<machineKey decryption=`"{0}`" decryptionKey=`"{1}`" validation=`"{2}`" validationKey=`"{3}`" />",
$decryptionAlgorithm.ToUpperInvariant(), $decryptionKey,
$validationAlgorithm.ToUpperInvariant(), $validationKey)
}
}
Per le applicazioni ASP.NET 4.0, è sufficiente chiamare Generate-MachineKey senza parametri per generare un <elemento machineKey> come indicato di seguito:
PS> Generate-MachineKey
<machineKey decryption="AES" decryptionKey="..." validation="HMACSHA256" validationKey="..." />
ASP.NET applicazioni 2.0 e 3.5 non supportano HMACSHA256. È invece possibile specificare SHA1 per generare un elemento machineKey> compatibile <come indicato di seguito:
PS> Generate-MachineKey -validation sha1
<machineKey decryption="AES" decryptionKey="..." validation="SHA1" validationKey="..." />
Non appena è disponibile un <elemento machineKey> , è possibile inserirlo nel file Web.config. L'elemento <machineKey> è valido solo nel file Web.config nella radice dell'applicazione e non è valido a livello di sottocartella.
<configuration>
<system.web>
<machineKey ... />
</system.web>
</configuration>
Per un elenco completo degli algoritmi supportati, eseguire la Guida Generate-MachineKey dal prompt Windows PowerShell.
Appendice B: Provisioning del Registro di sistema per rendere persistenti le chiavi generate automaticamente
Per impostazione predefinita, poiché ASP. NET generate automaticamente vengono mantenute nel registro HKCU, queste chiavi possono essere perse se il profilo utente non è stato caricato nel processo di lavoro IIS e quindi il pool di applicazioni viene riciclato. Questo scenario potrebbe influire sui provider di hosting condiviso che eseguono pool di applicazioni come account utente Windows standard.
Per risolvere questo problema, ASP.NET consente di rendere persistenti le chiavi generate automaticamente nel Registro di sistema HKLM anziché nel Registro di sistema HKCU. Questa operazione viene in genere eseguita utilizzando l'utilità aspnet_regiis (vedere le istruzioni nella sezione "Risoluzione 2a: utilizzare l'utilità aspnet_regiis"). Tuttavia, per gli amministratori che non vogliono eseguire questa utilità, è possibile usare lo script di Windows PowerShell seguente:
# Provisions the HKLM registry so that the specified user account can persist auto-generated machine keys.
function Provision-AutoGenKeys {
[CmdletBinding()]
param (
[ValidateSet("2.0", "4.0")]
[Parameter(Mandatory = $True)]
[string] $frameworkVersion,
[ValidateSet("32", "64")]
[Parameter(Mandatory = $True)]
[string] $architecture,
[Parameter(Mandatory = $True)]
[string] $upn
)
process {
# We require administrative permissions to continue.
if (-Not (new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Error "This cmdlet requires Administrator permissions."
return
}
# Open HKLM with an appropriate view into the registry
if ($architecture -eq "32") {
$regView = [Microsoft.Win32.RegistryView]::Registry32;
} else {
$regView = [Microsoft.Win32.RegistryView]::Registry64;
}
$baseRegKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $regView)
# Open ASP.NET base key
if ($frameworkVersion -eq "2.0") {
$expandedVersion = "2.0.50727.0"
} else {
$expandedVersion = "4.0.30319.0"
}
$aspNetBaseKey = $baseRegKey.OpenSubKey("SOFTWARE\Microsoft\ASP.NET\$expandedVersion", $True)
# Create AutoGenKeys subkey if it doesn't already exist
$autoGenBaseKey = $aspNetBaseKey.OpenSubKey("AutoGenKeys", $True)
if ($autoGenBaseKey -eq $null) {
$autoGenBaseKey = $aspNetBaseKey.CreateSubKey("AutoGenKeys")
}
# Get the SID for the user in question, which will allow us to get his AutoGenKeys subkey
$sid = (New-Object System.Security.Principal.WindowsIdentity($upn)).User.Value
# SYSTEM, ADMINISTRATORS, and the target SID get full access
$regSec = New-Object System.Security.AccessControl.RegistrySecurity
$regSec.SetSecurityDescriptorSddlForm("D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GA;;;$sid)")
$userAutoGenKey = $autoGenBaseKey.OpenSubKey($sid, $True)
if ($userAutoGenKey -eq $null) {
# Subkey didn't exist; create and ACL appropriately
$userAutoGenKey = $autoGenBaseKey.CreateSubKey($sid, [Microsoft.Win32.RegistryKeyPermissionCheck]::Default, $regSec)
} else {
# Subkey existed; make sure ACLs are correct
$userAutoGenKey.SetAccessControl($regSec)
}
}
}
Nell'esempio seguente viene illustrato come eseguire il provisioning delle voci del Registro di sistema HKLM appropriate per un pool di applicazioni eseguito come utente example@contoso.com (questo è l'UPN dell'account utente di Windows). Questo pool di applicazioni è un pool di applicazioni a 32 bit che esegue CLR v2.0 (ASP.NET 2.0 o 3.5).
PS> Provision-AutoGenKeys -FrameworkVersion 2.0 -Architecture 32 -UPN "example@contoso.com"
Se invece il pool di applicazioni è un pool di applicazioni a 64 bit che esegue CLR v4.0 (ASP.NET 4.0 o 4.5), il comando è il seguente:
PS> Provision-AutoGenKeys -FrameworkVersion 4.0 -Architecture 64 -UPN "example@contoso.com"
Anche se le chiavi generate automaticamente sono archiviate in HKLM, la sottochiave del Registro di sistema che contiene il materiale crittografico segreto di ogni account utente viene aggiunta a un elenco di controllo di accesso (ACL) in modo che il materiale crittografico non possa essere letto da altri account utente.
Appendice C: Crittografia dell'elemento <machineKey> nei file di configurazione
Gli amministratori del server potrebbero non volere che informazioni altamente riservate, come ad esempio il materiale delle chiavi machineKey>, <siano in formato testo normale nei file di configurazione. In questo caso, gli amministratori possono decidere di sfruttare una caratteristica di .NET Framework nota come "configurazione protetta". Questa funzionalità consente di crittografare determinate sezioni dei file .config. Se il contenuto di questi file di configurazione viene divulgato, il contenuto di queste sezioni rimarrà segreto.
Una breve panoramica della configurazione protetta è disponibile nel sito Web MSDN. Contiene anche un'esercitazione su come proteggere gli <elementi connectionStrings> e <machineKey> del file Web.config.