Beheben von Mac-Fehlern (View State Message Authentication Code, Authentifizierungscode)

Gilt für
.NET Framework 4.5 .NET Framework 3.5.1

Was ist der Ansichtszustand?

Der Ansichtszustand ist eine Information, die zwischen WebForms-Seiten (.aspx) in einer ASP.NET Anwendung roundtriped wird. Das HTML-Markup für das feld __VIEWSTATE sieht wie folgt aus:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
Ein Beispiel für ein Element, das im feld __VIEWSTATE gespeichert werden kann, ist der Text eines Button-Steuerelements. Wenn ein Benutzer auf die Schaltfläche klickt, kann der Button_Click-Ereignishandler den Text der Schaltfläche aus dem Ansichtszustandsfeld extrahieren. Eine ausführlichere Übersicht über den ASP.NET ASP.NET-Ansichtsstatus finden Sie auf der Msdn-Website (MSDN).

Da das Feld __VIEWSTATE wichtige Informationen enthält, die zum Rekonstruieren der Seite beim Postback verwendet werden, stellen Sie sicher, dass ein Angreifer dieses Feld nicht manipulieren kann. Wenn ein Angreifer eine böswillige __VIEWSTATE Nutzlast übermittelt hat, könnte der Angreifer die Anwendung potenziell dazu verleiten, eine Aktion auszuführen, die sie andernfalls nicht ausgeführt hätte.

Um diese Art von Manipulationsangriff zu verhindern, wird das feld __VIEWSTATE durch einen Nachrichtenauthentifizierungscode (Mac) geschützt. ASP.NET überprüft den MAC, der zusammen mit der __VIEWSTATE Nutzlast übermittelt wird, wenn ein Postback auftritt. Der Schlüssel, der zum Berechnen des MAC verwendet wird, wird im -Element der Anwendung in der Web.config-Datei angegeben. Da der Angreifer den Inhalt des <machineKey-Elements> nicht erraten kann, kann er keinen gültigen MAC bereitstellen, wenn der Angreifer versucht, die __VIEWSTATE Nutzlast zu manipulieren. ASP.NET erkennen, dass kein gültiger MAC bereitgestellt wurde, und ASP.NET lehnt die böswillige Anforderung ab.

Was verursacht MAC-Validierungsfehler?

Ein MAC-Überprüfungsfehler ähnelt dem folgenden Beispiel:

Hinweis

Serverfehler in der Anwendung "/".

Fehler bei der Überprüfung des Viewstate-MAC. Wenn diese Anwendung von einer Webfarm oder einem Cluster gehostet wird, stellen Sie sicher, dass die <machineKey-Konfiguration> den gleichen validationKey und validierungsalgorithmus angibt. AutoGenerate kann nicht in einem Cluster verwendet werden.

Beschreibung: Während der Ausführung der aktuellen Webanforderung ist eine Ausnahme ohne Behandlung aufgetreten. Weitere Informationen zu dem Fehler und dessen Ursprung im Code finden Sie in der Stapelüberwachung.

Ausnahmedetails: System.Web.HttpException: Fehler bei der Überprüfung von viewstate MAC. Wenn diese Anwendung von einer Webfarm oder einem Cluster gehostet wird, stellen Sie sicher, dass die <machineKey-Konfiguration> den gleichen validationKey und validierungsalgorithmus angibt. AutoGenerate kann nicht in einem Cluster verwendet werden.

Quellfehler: [Keine relevanten Quellzeilen]

Quelldatei: ... Zeile: 0

Stapelüberwachung:

[ViewStateException: Ungültiger viewstate-Wert.
Client-IP: ::1
Port: 40653
Referer: http://localhost:40643/MyPage.aspx
Pfad: /MyPage.aspx
User-Agent: Mozilla/5.0 (kompatibel; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
ViewState: ...]

[HttpException (0x80004005): Fehler bei der Überprüfung des Viewstate-MAC. Wenn diese Anwendung von einer Webfarm oder einem Cluster gehostet wird, stellen Sie sicher, dass die <machineKey-Konfiguration> den gleichen validationKey und validierungsalgorithmus angibt. AutoGenerate kann nicht in einem Cluster verwendet werden.

Weitere Informationen finden Sie unter http://go.microsoft.com/fwlink/?LinkID=314055.]
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, Zweck) +861
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter2.Deserialize(String serializedState, Zweck) +51
System.Web.UI.Util.DeserializeWithAssert(IStateFormatter2 formatter, String serializedState, Zweck) +67
System.Web.UI.HiddenFieldPageStatePersister.Load() +444
System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +368
System.Web.UI.Page.LoadAllState() +109
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +7959
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +429
System.Web.UI.Page.ProcessRequest() +125
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +48
System.Web.UI.Page.ProcessRequest(HttpContext context) +234
ASP.mypage_aspx. ProcessRequest(HttpContext context) in ... :0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +1300
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +140

Ursache 1: Die Webanwendung wird in einer Farm (Umgebung mit mehreren Servern) ausgeführt.

ASP.NET generiert automatisch einen kryptografischen Schlüssel für jede Anwendung und speichert den Schlüssel in der HKCU-Registrierungsstruktur. Dieser automatisch generierte Schlüssel wird verwendet, wenn in der Konfiguration der Anwendung kein explizites <machineKey-Element> vorhanden ist. Da sich dieser automatisch generierte Schlüssel jedoch lokal auf dem Computer befindet, auf dem der Schlüssel erstellt wurde, verursacht dieses Szenario ein Problem für Anwendungen, die in einer Farm ausgeführt werden. Jeder Server in der Farm generiert einen eigenen lokalen Schlüssel, und keiner der Server in der Farm stimmt dem zu verwendenden Schlüssel zu. Wenn ein Server eine __VIEWSTATE Nutzlast generiert, die von einem anderen Server verbraucht wird, tritt beim Consumer ein MAC-Validierungsfehler auf.

  • Lösung 1a: Erstellen eines expliziten <machineKey-Elements>

    Durch Hinzufügen eines expliziten <machineKey-Elements> zur Web.config-Datei der Anwendung weist der Entwickler ASP.NET an, den automatisch generierten kryptografischen Schlüssel nicht zu verwenden. Anweisungen zum Generieren eines <machineKey-Elements> finden Sie in Anhang A. Nachdem dieses Element der Web.config-Datei hinzugefügt wurde, stellen Sie die Anwendung auf jedem Server in der Farm erneut bereit.

    Hinweis Einige Webhostingdienste, z. B. Microsoft Azure Websites, führen Schritte aus, um den automatisch generierten Schlüssel jeder Anwendung auf ihren Back-End-Servern zu synchronisieren. Dadurch können Anwendungen, die kein explizites <machineKey-Element> angegeben haben, weiterhin in diesen Umgebungen arbeiten, auch wenn die Anwendung in einer Farm ausgeführt wird. Wenn Ihre Anwendung auf einem Hostingdienst eines Drittanbieters ausgeführt wird, wenden Sie sich bitte an Ihren Hostinganbieter, um festzustellen, ob diese Situation für Sie zutrifft.

  • Lösung 1b: Aktivieren der Affinität im Lastenausgleich

    Wenn Ihre Websites hinter einem Lastenausgleich betrieben werden, können Sie die Serveraffinität aktivieren, um das Problem vorübergehend zu umgehen. Dadurch wird sichergestellt, dass ein bestimmter Client nur mit einem physischen Server hinter dem Lastenausgleich interagiert, sodass alle kryptografischen Nutzdaten sowohl vom selben Server generiert als auch genutzt werden.

    Dies sollte nicht als langfristige Lösung des Problems betrachtet werden. Selbst wenn die Serveraffinität aktiviert ist, leiten die meisten Lastenausgleichsmodule den Client an einen anderen physischen Server um, wenn der ursprüngliche Server, zu dem die Lastenausgleichsmodule affinitiert wurden, offline geschaltet wird. Dies führt dazu, dass der neue Server kryptografische Nutzlasten (z. B. __VIEWSTATE, Formularauthentifizierungstickets, MVCs-Antifälschungstoken und andere Dienste) ablehnt, die der Client derzeit besitzt.

    Die Verwendung eines expliziten <machineKey-Elements> und die erneute Bereitstellung der Anwendung sollte gegenüber der Aktivierung der Serveraffinität bevorzugt werden.

Ursache 2: Der Arbeitsprozess verwendet die IIS 7.0-Anwendungspoolidentität.

Internetinformationsdienste (IIS) 7.0 (Windows Vista, Windows Server 2008) führte die Anwendungspoolidentität ein, einen neuen Isolationsmechanismus, der dazu beiträgt, die Sicherheit für Server zu erhöhen, auf denen ASP.NET Anwendungen ausgeführt werden. Websites, die unter der Anwendungspoolidentität ausgeführt werden, haben jedoch keinen Zugriff auf die HKCU-Registrierung. Hier speichert die ASP.NET Runtime ihre automatisch generierten <machineKey-Schlüssel> . Dies führt dazu, dass ASP.NET den automatisch generierten Schlüssel nicht beibehalten können, wenn der Anwendungspool zurückgesetzt wird. Daher wird jedes Mal, wenn w3wp.exe zurückgesetzt wird, ein neuer temporärer Schlüssel generiert.

Hinweis Dies ist in IIS 7.5 (Windows 7, Windows Server 2008 R2) und höheren Versionen kein Problem. In diesen Versionen von IIS können ASP.NET ihre automatisch generierten Schlüssel an einem anderen Speicherort speichern, der das Zurücksetzen des Anwendungspools übersteht.

  • Lösung 2a: Verwenden des Hilfsprogramms aspnet_regiis

    ASP.NET Installationen enthalten ein Hilfsprogramm ,aspnet_regiis.exe. Dieses Hilfsprogramm ermöglicht ASP.NET Schnittstelle mit IIS, um die Konfigurationen auszuführen, die zum Ausführen einer verwalteten Anwendung erforderlich sind. Eine dieser Konfigurationen erstellt die erforderlichen Schlüssel in der Registrierungsstruktur, um die Persistenz automatisch generierter Computerschlüssel zu ermöglichen.

    Zunächst müssen Sie ermitteln, welchen Anwendungspool Ihre Website verwendet. Dies kann mithilfe des Inetmgr-Hilfsprogramms ermittelt werden, das in IIS enthalten ist. Wählen Sie Ihre Website in der Strukturansicht auf der linken Seite aus, klicken Sie mit der rechten Maustaste auf Websitverwalten, und klicken Sie dann auf Erweiterte Einstellungen. Im angezeigten Dialogfeld wird der Name des Anwendungspools angezeigt.

    Erweiterte Einstellungen

    Führen Sie die folgenden Schritte aus, um ein Gerüst für die entsprechenden Registrierungsschlüssel für einen ASP.NET 4.0-Anwendungspool zu erstellen:

    1. Öffnen Sie eine administrative Eingabeaufforderung.

    2. Suchen Sie das entsprechende Verzeichnis, je nachdem, ob Ihr Anwendungspool 32-Bit oder 64-Bit ist:

      • 32-Bit-Anwendungspool: cd /d %windir%\Microsoft.NET\Framework\v4.0.30319
      • 64-Bit-Anwendungspool: cd /d %windir%\Microsoft.NET\Framework64\v4.0.30319
    3. Wechseln Sie zum Verzeichnis, geben Sie den folgenden Befehl ein, und drücken Sie dann die EINGABETASTE:

      aspnet_regiis -ga "IIS APPPOOL\app-pool-name"

    Wenn der Anwendungspool ein ASP.NET 2.0- oder 3.5-Anwendungspool ist, führen Sie die folgenden Schritte aus:

    1. Öffnen Sie eine administrative Eingabeaufforderung.

    2. Suchen Sie das entsprechende Verzeichnis, je nachdem, ob Ihr Anwendungspool 32-Bit oder 64-Bit ist:

      • 32-Bit-Anwendungspool: cd /d %windir%\Microsoft.NET\Framework\v2.0.50727
      • 64-Bit-Anwendungspool: cd /d %windir%\Microsoft.NET\Framework64\v2.0.50727
    3. Wechseln Sie zum Verzeichnis, geben Sie den folgenden Befehl ein, und drücken Sie dann die EINGABETASTE:

      aspnet_regiis -ga "IIS APPPOOL\app-pool-name"

    Wenn Ihr Anwendungspool beispielsweise den Namen Mein App-Pool hat (wie in der vorherigen Abbildung), führen Sie den folgenden Befehl aus:
     
    aspnet_regiis -ga "IIS APPPOOL\Mein App-Pool"

    Hinweis Die Systemdienste APPHOSTSVC und WAS müssen möglicherweise ausgeführt werden, damit das hilfsprogramm aspnet_regiis IIS APPPOOL\* ordnungsgemäß auflösen kann.

  • Lösung 2b: Erstellen eines expliziten <machineKey-Elements>

    Durch Hinzufügen eines expliziten <machineKey-Elements> zur Web.config-Datei der Anwendung weist der Entwickler ASP.NET an, den automatisch generierten kryptografischen Schlüssel nicht zu verwenden. Anweisungen zum Generieren eines <machineKey-Elements> finden Sie in Anhang A.

Ursache 3: Der Anwendungspool wird mithilfe von LoadUserProfile=false konfiguriert.

Wenn der Anwendungspool mit einer benutzerdefinierten Identität ausgeführt wird, hat IIS das Benutzerprofil für die Identität möglicherweise nicht geladen. Dies hat den Nebeneffekt, dass die HKCU-Registrierung für ASP.NET nicht verfügbar ist, um den automatisch generierten <machineKey> beizubehalten. Daher wird bei jedem Neustart der Anwendung ein neuer automatisch generierter Schlüssel erstellt. Weitere Informationen finden Sie auf der Microsoft-Website im Abschnitt Benutzerprofil .

  • Lösung 3a: Verwenden des Hilfsprogramms aspnet_regiis

    Die Anweisungen hierfür sind identisch mit Resolution 2a. Weitere Informationen finden Sie in diesem Abschnitt.

  • Lösung 3b: Verwenden eines expliziten <machineKey>

    Durch Hinzufügen eines expliziten <machineKey-Elements> zur Web.config-Datei der Anwendung weist der Entwickler ASP.NET an, den automatisch generierten kryptografischen Schlüssel nicht zu verwenden. Anweisungen zum Generieren eines <machineKey-Elements> finden Sie in Anhang A.

  • Lösung 3c: Manuelles Bereitstellen der erforderlichen HKCU-Registrierungsschlüssel

    Wenn Sie das Hilfsprogramm aspnet_regiis nicht ausführen können, können Sie ein Windows PowerShell Skript verwenden, um die entsprechenden Registrierungsschlüssel in HKCU bereitzustellen. Weitere Informationen finden Sie in Anhang B .

  • Lösung 3d: Festlegen von LoadUserProfile=true für diesen Anwendungspool

    Sie können auch das Laden des Benutzerprofils innerhalb dieses Anwendungspools aktivieren. Dadurch werden die HKCU-Registrierungsstruktur, der temporäre Ordner und andere benutzerspezifische Speicherorte für die Anwendung verfügbar. Dies kann jedoch zu einer erhöhten Datenträger- oder Arbeitsspeicherauslastung für den Arbeitsprozess führen. Weitere Informationen zum Aktivieren dieser Einstellung finden Sie im -Element .

Ursache 4: Die Page.ViewStateUserKey-Eigenschaft weist einen falschen Wert auf.

Softwareentwickler können die Page.ViewStateUserKey-Eigenschaft verwenden, um dem Feld __VIEWSTATE websiteübergreifenden Schutz vor Anforderungsfälschungen hinzuzufügen. Wenn Sie die Page.ViewStateUserKey-Eigenschaft verwenden, wird sie in der Regel auf einen Wert wie den Benutzernamen des aktuellen Benutzers oder den Sitzungsbezeichner des Benutzers festgelegt. Die Projektvorlagen für WebForms-Anwendungen in Microsoft Visual Studio 2012 und höheren Versionen enthalten Beispiele, die diese Eigenschaft verwenden. Weitere Informationen finden Sie im Thema Page.ViewStateUserKey Property auf der MSDN-Website (MSDN).

Wenn die ViewStateUserKey-Eigenschaft angegeben wird, wird ihr Wert zum Zeitpunkt der Generierung in __VIEWSTATE verbrannt. Wenn das feld __VIEWSTATE verwendet wird, überprüft der Server die ViewStateUserKey-Eigenschaft der aktuellen Seite und überprüft sie anhand des Werts, der zum Generieren des __VIEWSTATE Felds verwendet wurde. Wenn die Werte nicht übereinstimmen, wird die Anforderung als potenziell böswillig abgelehnt.

Ein Beispiel für einen ViewStateUserKey-bezogenen Fehler wäre ein Client, der zwei Registerkarten im Browser geöffnet hat. Der Client ist als Benutzer A angemeldet, und auf der ersten Registerkarte wird eine Seite mit einem __VIEWSTATE gerendert, dessen ViewStateUserKey-Eigenschaft "Benutzer A" enthält. Auf der zweiten Registerkarte meldet sich der Client ab und meldet sich dann wieder als Benutzer B an. Der Client wechselt zurück zur ersten Registerkarte und sendet das Formular. Die ViewStateUserKey-Eigenschaft kann "Benutzer B" enthalten (weil dies das Authentifizierungscooky des Clients sagt). Das __VIEWSTATE Feld, das der Client übermittelt hat, enthält jedoch "Benutzer A". Dieser Konflikt verursacht den Fehler.

  • Lösung 4a: Überprüfen, ob ViewStateUserKey richtig festgelegt ist

    Wenn Ihre Anwendung die ViewStateUserKey-Eigenschaft verwendet, überprüfen Sie, ob der Wert der Eigenschaft sowohl beim Generieren des Ansichtszustands als auch beim Verbrauch identisch ist. Wenn Sie den Benutzernamen des aktuell angemeldeten Benutzers verwenden, stellen Sie sicher, dass der Benutzer weiterhin angemeldet ist und dass sich die Identität des Benutzers zum Zeitpunkt des Postbacks nicht geändert hat. Wenn Sie die Sitzungs-ID des aktuellen Benutzers verwenden, stellen Sie sicher, dass für die Sitzung kein Timeout aufgetreten ist.

    Wenn Sie in einer Farmumgebung ausführen, stellen Sie sicher, dass die <machineKey-Elemente> übereinstimmen. Anweisungen zum Generieren dieser Elemente finden Sie in Anhang A .

          

Anhang A: Generieren eines <machineKey-Elements>

Hinweis

Sicherheitswarnung

Es gibt viele Websites, die mit einem Klick auf eine Schaltfläche ein <machineKey-Element> für Sie generieren. Verwenden Sie niemals ein <machineKey-Element> , das Sie von einer dieser Websites abgerufen haben. Es ist unmöglich zu wissen, ob diese Schlüssel sicher erstellt wurden oder ob sie in einer geheimen Datenbank aufgezeichnet werden. Sie sollten immer nur machineKey-Konfigurationselemente> verwenden<, die Sie selbst erstellt haben.

        
Um selbst ein <machineKey-Element> zu generieren, können Sie das folgende Windows PowerShell Skript verwenden:


# 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)
  }
}

Für ASP.NET 4.0-Anwendungen können Sie einfach Generate-MachineKey ohne Parameter aufrufen, um ein <machineKey-Element> wie folgt zu generieren:


PS> Generate-MachineKey
<machineKey decryption="AES" decryptionKey="..." validation="HMACSHA256" validationKey="..." />

ASP.NET 2.0- und 3.5-Anwendungen unterstützen HMACSHA256 nicht. Stattdessen können Sie SHA1 angeben, um ein kompatibles <machineKey-Element> wie folgt zu generieren:


PS> Generate-MachineKey -validation sha1
<machineKey decryption="AES" decryptionKey="..." validation="SHA1" validationKey="..." />

Sobald Sie über ein <machineKey-Element> verfügen, können Sie es in die Web.config-Datei einfügen. Das <machineKey-Element> ist nur in der Web.config-Datei im Stammverzeichnis Ihrer Anwendung gültig und auf Unterordnerebene ungültig.


<configuration>
  <system.web>
    <machineKey ... />
  </system.web>
</configuration>

Um eine vollständige Liste der unterstützten Algorithmen zu erhalten, führen Sie hilfe Generate-MachineKey an der Windows PowerShell-Eingabeaufforderung aus.

Anhang B: Bereitstellen der Registrierung zum Beibehalten automatisch generierter Schlüssel

Standardmäßig, weil ASP. Automatisch generierte NETs-Schlüssel werden in der HKCU-Registrierung beibehalten. Diese Schlüssel gehen möglicherweise verloren, wenn das Benutzerprofil nicht in den IIS-Arbeitsprozess geladen wurde und der Anwendungspool dann wiederverwendet wird. Dieses Szenario könnte sich auf anbieter mit freigegebenem Hosting auswirken, die Anwendungspools als Windows-Standardbenutzerkonten ausführen.

Um diese Situation zu umgehen, ermöglicht ASP.NET das Beibehalten der automatisch generierten Schlüssel in der HKLM-Registrierung anstelle der HKCU-Registrierung. Dies erfolgt in der Regel mithilfe des Hilfsprogramms aspnet_regiis (siehe Anweisungen im Abschnitt "Resolution 2a: Use the aspnet_regiis utility" (Lösung 2a: Verwenden des Hilfsprogramms aspnet_regiis). Für Administratoren, die dieses Hilfsprogramm nicht ausführen möchten, kann stattdessen das folgende Windows PowerShell Skript verwendet werden:


# 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)
    }
  }
}

Das folgende Beispiel zeigt, wie die entsprechenden HKLM-Registrierungseinträge für einen Anwendungspool bereitgestellt werden, example@contoso.com der als Benutzer ausgeführt wird (dies ist der UPN des Windows-Benutzerkontos). Dieser Anwendungspool ist ein 32-Bit-Anwendungspool, in dem clR v2.0 (ASP.NET 2.0 oder 3.5) ausgeführt wird.


PS> Provision-AutoGenKeys -FrameworkVersion 2.0 -Architecture 32 -UPN "example@contoso.com"

Wenn der Anwendungspool stattdessen ein 64-Bit-Anwendungspool ist, der CLR v4.0 (ASP.NET 4.0 oder 4.5) ausführt, lautet der Befehl wie folgt:


PS> Provision-AutoGenKeys -FrameworkVersion 4.0 -Architecture 64 -UPN "example@contoso.com"

Obwohl die automatisch generierten Schlüssel in HKLM gespeichert werden, wird der Registrierungsunterschlüssel, der das geheime kryptografische Material jedes Benutzerkontos enthält, einer Zugriffssteuerungsliste (Access Control List, ACL) hinzugefügt, sodass das kryptografische Material nicht von anderen Benutzerkonten gelesen werden kann.

Anhang C: Verschlüsseln des <machineKey-Elements> in Konfigurationsdateien

Serveradministratoren möchten möglicherweise nicht, dass hochsensible Informationen wie das <machineKey-Schlüsselmaterial> in bein-Klartext-Formularen in Konfigurationsdateien angezeigt werden. Wenn dies der Fall ist, können Administratoren entscheiden, ein .NET Framework Feature zu nutzen, das als "geschützte Konfiguration" bezeichnet wird. Mit diesem Feature können Sie bestimmte Abschnitte der .config Dateien verschlüsseln. Wenn der Inhalt dieser Konfigurationsdateien jemals offengelegt wird, bleibt der Inhalt dieser Abschnitte weiterhin geheim.

Eine kurze Übersicht über die geschützte Konfiguration finden Sie auf der MSDN-Website. Es enthält auch ein Tutorial zum Schützen der <connectionStrings> - und <machineKey-Elemente> der Web.config-Datei.