뷰 상태가란?
보기 상태는 ASP.NET 애플리케이션의 WebForms(.aspx) 페이지 간에 왕복되는 정보입니다. __VIEWSTATE 필드에 대한 HTML 태그는 다음과 유사합니다.
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
__VIEWSTATE 필드에 저장할 수 있는 항목의 한 가지 예는 단추 컨트롤의 텍스트입니다. 사용자가 단추를 클릭하면 Button_Click 이벤트 처리기가 보기 상태 필드에서 단추의 텍스트를 추출할 수 있습니다.
ASP.NET 보기 상태에 대한 훨씬 더 자세한 개요는 MSDN(Microsoft Developer Network) 웹 사이트의 ASP.NET 상태 보기 개요 항목을 참조하세요.
__VIEWSTATE 필드에는 포스트백에서 페이지를 재구성하는 데 사용되는 중요한 정보가 포함되어 있으므로 공격자가 이 필드를 변조할 수 없는지 확인합니다. 공격자가 악의적인 __VIEWSTATE 페이로드를 제출한 경우 공격자는 애플리케이션이 수행하지 않았을 작업을 수행하도록 속일 수 있습니다.
이러한 종류의 변조 공격을 방지하기 위해 __VIEWSTATE 필드는 MAC(메시지 인증 코드)로 보호됩니다. ASP.NET 포스트백이 발생할 때 __VIEWSTATE 페이로드와 함께 제출되는 MAC의 유효성을 검사합니다. MAC을 계산하는 데 사용되는 키는 Web.config 파일의 애플리케이션 요소 에 지정됩니다. 공격자가 machineKey> 요소의 <내용을 추측할 수 없으므로 공격자가 __VIEWSTATE 페이로드를 변조하려고 하면 공격자가 유효한 MAC을 제공할 수 없습니다. ASP.NET 유효한 MAC이 제공되지 않았음을 감지하고 ASP.NET 악의적인 요청을 거부합니다.
MAC 유효성 검사 오류의 원인은 무엇인가요?
MAC 유효성 검사 오류는 다음 예제와 유사합니다.
참고
'/' 애플리케이션의 서버 오류입니다.
viewstate MAC의 유효성 검사에 실패했습니다. 이 애플리케이션이 웹 팜 또는 클러스터에서 호스트되는 경우 machineKey> 구성이 <동일한 validationKey 및 유효성 검사 알고리즘을 지정하는지 확인합니다. 클러스터에서 자동 생성을 사용할 수 없습니다.
설명: 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 오류 및 코드에서 발생한 위치에 대한 자세한 내용은 스택 추적을 검토하세요.
예외 세부 정보: System.Web.HttpException: viewstate MAC의 유효성 검사에 실패했습니다. 이 애플리케이션이 웹 팜 또는 클러스터에서 호스트되는 경우 machineKey> 구성이 <동일한 validationKey 및 유효성 검사 알고리즘을 지정하는지 확인합니다. 클러스터에서 자동 생성을 사용할 수 없습니다.
원본 오류: [관련 소스 줄 없음]
원본 파일: ... 줄: 0
스택 추적:
[ViewStateException: 잘못된 viewstate입니다.
클라이언트 IP: ::1
포트: 40653
참조자: http://localhost:40643/MyPage.aspx
경로: /MyPage.aspx
사용자 에이전트: Mozilla/5.0(호환; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
ViewState: ...]
[httpException(0x80004005): viewstate MAC의 유효성 검사에 실패했습니다. 이 애플리케이션이 웹 팜 또는 클러스터에서 호스트되는 경우 machineKey> 구성이 <동일한 validationKey 및 유효성 검사 알고리즘을 지정하는지 확인합니다. 클러스터에서 자동 생성을 사용할 수 없습니다.
자세한 내용은 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, Purpose purpose) +861
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter2.Deserialize(String serializedState, Purpose purpose) +51
System.Web.UI.Util.DeserializeWithAssert(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(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 컨텍스트) +48
System.Web.UI.Page.ProcessRequest(HttpContext 컨텍스트) +234
ASP.mypage_aspx. 의 ProcessRequest(HttpContext 컨텍스트) ... :0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +1300
System.Web.HttpApplication.ExecuteStep(IExecutionStep 단계, 부울& completedSynchronously) +140
원인 1: 웹 애플리케이션이 팜(다중 서버 환경)에서 실행되고 있습니다.
ASP.NET 각 애플리케이션에 대한 암호화 키를 자동으로 생성하고 HKCU 레지스트리 하이브에 키를 저장합니다. 이 자동 생성된 키는 애플리케이션 구성에 명시적 <machineKey> 요소가 없는 경우에 사용됩니다. 그러나 이 자동 생성된 키는 키를 만든 컴퓨터에 로컬이므로 이 시나리오에서는 팜에서 실행되는 애플리케이션에 문제가 발생합니다. 팜의 각 서버는 자체 로컬 키를 생성하며 팜의 서버 중 어느 것도 사용할 키에 동의하지 않습니다. 그 결과 한 서버가 다른 서버에서 사용하는 __VIEWSTATE 페이로드를 생성하는 경우 소비자는 MAC 유효성 검사 오류가 발생합니다.
해결 방법 1a: 명시적 <machineKey> 요소 만들기
명시적 <machineKey> 요소를 애플리케이션의 Web.config 파일에 추가하면 개발자는 ASP.NET 자동으로 생성된 암호화 키를 사용하지 않도록 지시합니다. machineKey> 요소를 생성하는 방법에 대한 지침은 부록 A를 <참조하세요. 이 요소가 Web.config 파일에 추가된 후 팜의 각 서버에 애플리케이션을 다시 배포합니다.
참고 Microsoft Azure 웹 사이트와 같은 일부 웹 호스팅 서비스는 백 엔드 서버에서 각 애플리케이션의 자동 생성된 키를 동기화하는 단계를 수행합니다. 이렇게 하면 명시적 <machineKey> 요소를 지정하지 않은 애플리케이션이 팜에서 실행 중인 경우에도 이러한 환경에서 계속 작동할 수 있습니다. 애플리케이션이 타사 호스팅 서비스에서 실행되는 경우 호스팅 공급자에게 문의하여 이 상황이 적용되는지 확인하세요.
해결 방법 1b: 부하 분산 장치에서 선호도 사용
사이트가 부하 분산 장치 뒤에서 작동하는 경우 서버 선호도를 사용하도록 설정하여 일시적으로 문제를 해결할 수 있습니다. 이렇게 하면 지정된 클라이언트가 부하 분산 장치 뒤에 있는 하나의 물리적 서버와만 상호 작용하여 모든 암호화 페이로드가 동일한 서버에 의해 생성되고 소비되도록 할 수 있습니다.
이는 문제에 대한 장기적인 해결책으로 간주되어서는 안 됩니다. 서버 선호도를 사용하도록 설정한 경우에도 부하 분산 장치가 활성화된 원래 서버가 오프라인 상태가 되면 대부분의 부하 분산 장치는 클라이언트를 다른 물리적 서버로 리디렉션합니다. 이로 인해 새 서버는 클라이언트가 현재 가지고 있는 암호화 페이로드(예: __VIEWSTATE, 양식 인증 티켓, MVC 위조 방지 토큰 및 기타 서비스)를 거부합니다.
명시적 <machineKey> 요소를 사용하고 애플리케이션을 다시 배포하는 것이 서버 선호도를 사용하도록 설정하는 것보다 선호되어야 합니다.
원인 2: 작업자 프로세스는 IIS 7.0 애플리케이션 풀 ID를 사용합니다.
IIS(인터넷 정보 서비스) 7.0(Windows Vista, Windows Server 2008)에는 ASP.NET 애플리케이션을 실행하는 서버에 대한 보안을 강화하는 데 도움이 되는 새로운 격리 메커니즘인 애플리케이션 풀 ID가 도입되었습니다. 그러나 애플리케이션 풀 ID에서 실행되는 사이트는 HKCU 레지스트리에 액세스할 수 없습니다. 여기서 ASP.NET 런타임은 자동 생성된 <machineKey> 키를 저장합니다. 그 결과 ASP.NET 애플리케이션 풀이 다시 설정될 때 자동 생성된 키를 유지할 수 없습니다. 따라서 w3wp.exe 다시 설정될 때마다 새 임시 키가 생성됩니다.
참고 IIS 7.5(Windows 7, Windows Server 2008 R2) 이상 버전에서는 문제가 되지 않습니다. 이러한 버전의 IIS에서 ASP.NET 애플리케이션 풀 재설정에서 유지되는 다른 위치에 자동 생성된 키를 유지할 수 있습니다.
해결 방법 2a: aspnet_regiis 유틸리티 사용
ASP.NET 설치에는 유틸리티aspnet_regiis.exe포함 됩니다. 이 유틸리티를 사용하면 IIS와 인터페이스를 ASP.NET 관리되는 애플리케이션을 실행하는 데 필요한 구성을 수행할 수 있습니다. 이러한 구성 중 하나는 레지스트리 하이브에 필요한 키를 만들어 자동 생성된 컴퓨터 키의 지속성을 사용하도록 설정합니다.
먼저 사이트에서 사용 중인 애플리케이션 풀을 결정해야 합니다. IIS에 포함된 inetmgr 유틸리티를 사용하여 확인할 수 있습니다. 왼쪽의 트리 보기에서 사이트를 선택하고 Websit e 관리를마우스 오른쪽 단추로 클릭한 다음 고급 설정을 클릭합니다. 표시되는 대화 상자에 애플리케이션 풀 이름이 표시됩니다.
ASP.NET 4.0 애플리케이션 풀에 적합한 레지스트리 키를 스캐폴드하려면 다음 단계를 수행합니다.
관리 명령 프롬프트를 엽니다.
애플리케이션 풀이 32비트인지 64비트인지에 따라 적절한 디렉터리를 찾습니다.
- 32비트 애플리케이션 풀: cd /d %windir%\Microsoft.NET\Framework\v4.0.30319
- 64비트 애플리케이션 풀: cd /d %windir%\Microsoft.NET\Framework64\v4.0.30319
디렉터리로 이동하고 다음 명령을 입력한 다음 Enter 키를 누릅니다.
aspnet_regiis -ga "IIS APPPOOL\app-pool-name"
애플리케이션 풀이 ASP.NET 2.0 또는 3.5 애플리케이션 풀인 경우 다음 단계를 수행합니다.
관리 명령 프롬프트를 엽니다.
애플리케이션 풀이 32비트인지 64비트인지에 따라 적절한 디렉터리를 찾습니다.
- 32비트 애플리케이션 풀: cd /d %windir%\Microsoft.NET\Framework\v2.0.50727
- 64비트 애플리케이션 풀: cd /d %windir%\Microsoft.NET\Framework64\v2.0.50727
디렉터리로 이동하고 다음 명령을 입력한 다음 Enter 키를 누릅니다.
aspnet_regiis -ga "IIS APPPOOL\app-pool-name"
예를 들어 애플리케이션 풀의 이름이 내 앱 풀(이전 이미지와 같이)인 경우 다음 명령을 실행합니다.
aspnet_regiis -ga "IIS APPPOOL\내 앱 풀"참고 시스템 서비스 APPHOSTSVC 및 WAS는 IIS APPPOOL\* 이름을 적절하게 resolve aspnet_regiis 유틸리티에 대해 실행되어야 할 수 있습니다.
해결 방법 2b: 명시적 <machineKey> 요소 만들기
명시적 <machineKey> 요소를 애플리케이션의 Web.config 파일에 추가하면 개발자는 ASP.NET 자동으로 생성된 암호화 키를 사용하지 않도록 지시합니다. machineKey> 요소를 생성하는 방법에 대한 지침은 부록 A를 <참조하세요.
원인 3: 애플리케이션 풀은 LoadUserProfile=false를 사용하여 구성됩니다.
애플리케이션 풀이 사용자 지정 ID를 사용하여 실행되는 경우 IIS에서 ID에 대한 사용자 프로필을 로드하지 않았을 수 있습니다. 이로 인해 ASP.NET 자동 생성된 <machineKey를 유지하기 위해 HKCU 레지스트리를 사용할 수 없게 만드는 부작용이> 있습니다. 따라서 애플리케이션이 다시 시작될 때마다 새 자동 생성 키가 만들어집니다. 자세한 내용은 Microsoft 웹 사이트의 사용자 프로필 섹션을 참조하세요.
해결 방법 3a: aspnet_regiis 유틸리티 사용
이에 대한 지침은 해상도 2a와 동일합니다. 자세한 내용은 해당 섹션을 참조하세요.
해결 방법 3b: 명시적 <machineKey 사용>
명시적 <machineKey> 요소를 애플리케이션의 Web.config 파일에 추가하면 개발자는 ASP.NET 자동으로 생성된 암호화 키를 사용하지 않도록 지시합니다. machineKey> 요소를 생성하는 방법에 대한 지침은 부록 A를 <참조하세요.
해결 방법 3c: 필요한 HKCU 레지스트리 키를 수동으로 프로비전
aspnet_regiis 유틸리티를 실행할 수 없는 경우 Windows PowerShell 스크립트를 사용하여 HKCU에서 적절한 레지스트리 키를 프로비전할 수 있습니다. 자세한 내용은 부록 B 를 참조하세요.
해결 방법 3d: 이 애플리케이션 풀에 대해 LoadUserProfile=true 설정
이 애플리케이션 풀 내에서 사용자 프로필을 로드하도록 설정할 수도 있습니다. 이렇게 하면 HKCU 레지스트리 하이브, 임시 폴더 및 기타 사용자별 스토리지 위치를 애플리케이션에서 사용할 수 있습니다. 그러나 이로 인해 작업자 프로세스의 디스크 또는 메모리 사용량이 증가할 수 있습니다. 이 설정을 사용하도록 설정하는 방법에 대한 자세한 내용은 요소를 참조하세요.
원인 4: Page.ViewStateUserKey 속성에 잘못된 값이 있습니다.
소프트웨어 개발자는 Page.ViewStateUserKey 속성을 사용하여 사이트 간 요청 위조 보호를 __VIEWSTATE 필드에 추가할 수 있습니다. Page.ViewStateUserKey 속성을 사용하는 경우 일반적으로 현재 사용자의 사용자 이름 또는 사용자의 세션 식별자와 같은 값으로 설정됩니다. Microsoft Visual Studio 2012 이상 버전의 WebForms 애플리케이션에 대한 프로젝트 템플릿에는 이 속성을 사용하는 샘플이 포함되어 있습니다. 자세한 내용은 MSDN(Microsoft Developer Network) 웹 사이트의 Page.ViewStateUserKey 속성 항목을 참조하세요.
ViewStateUserKey 속성을 지정하면 해당 값은 생성 시 __VIEWSTATE 발생합니다. __VIEWSTATE 필드를 사용하는 경우 서버는 현재 Page의 ViewStateUserKey 속성을 확인하고 __VIEWSTATE 필드를 생성하는 데 사용된 값에 대해 유효성을 검사합니다. 값이 일치하지 않으면 요청이 잠재적으로 악의적인 것으로 거부됩니다.
ViewStateUserKey 관련 오류의 예로는 브라우저에서 두 개의 탭이 열려 있는 클라이언트가 있습니다. 클라이언트가 사용자 A로 로그인되고 첫 번째 탭에서 Page는 ViewStateUserKey 속성에 "User A"가 포함된 __VIEWSTATE 사용하여 렌더링됩니다. 두 번째 탭에서 클라이언트는 로그아웃한 다음 사용자 B로 다시 로그인합니다. 클라이언트가 첫 번째 탭으로 돌아가서 양식을 제출합니다. ViewStateUserKey 속성에는 "사용자 B"가 포함될 수 있습니다(클라이언트의 인증 쿠키가 말하는 내용이기 때문). 그러나 클라이언트가 제출한 __VIEWSTATE 필드에는 "사용자 A"가 포함됩니다. 이 불일치로 인해 오류가 발생합니다.
해결 방법 4a: ViewStateUserKey가 올바르게 설정되었는지 확인
애플리케이션에서 ViewStateUserKey 속성을 사용하는 경우 뷰 상태가 생성될 때와 사용하는 경우 속성의 값이 동일한지 확인합니다. 현재 로그인한 사용자의 사용자 이름을 사용하는 경우 사용자가 여전히 로그인되어 있고 포스트백 시 사용자의 ID가 변경되지 않았는지 확인합니다. 현재 사용자의 세션 식별자를 사용하는 경우 세션 시간이 초과되지 않았는지 확인합니다.
팜 환경에서 실행하는 경우 machineKey> 요소가 일치하는지 확인<합니다. 이러한 요소를 생성하는 방법에 대한 지침은 부록 A 를 참조하세요.
부록 A: machineKey> 요소를 생성하는 <방법
참고
보안 경고
단추를 클릭하여 machineKey> 요소를 생성하는 <많은 웹 사이트가 있습니다. 이러한 사이트 중 하나에서 가져온 machineKey> 요소를 사용하지 <마세요. 이러한 키가 안전하게 만들어졌는지 또는 비밀 데이터베이스에 기록되고 있는지 알 수 없습니다. 직접 만든 machineKey> 구성 요소만 사용해야 <합니다.
machineKey 요소를 직접 생성<하려면 다음 Windows PowerShell 스크립트를 사용할 수 있습니다.>
# 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)
}
}
ASP.NET 4.0 애플리케이션의 경우 다음과 같이 매개 변수 없이 Generate-MachineKey 호출하여 machineKey> 요소를 생성<할 수 있습니다.
PS> Generate-MachineKey
<machineKey decryption="AES" decryptionKey="..." validation="HMACSHA256" validationKey="..." />
ASP.NET 2.0 및 3.5 애플리케이션은 HMACSHA256 지원하지 않습니다. 대신 다음과 같이 SHA1을 지정하여 호환 <되는 machineKey> 요소를 생성할 수 있습니다.
PS> Generate-MachineKey -validation sha1
<machineKey decryption="AES" decryptionKey="..." validation="SHA1" validationKey="..." />
machineKey> 요소가 있는 <즉시 Web.config 파일에 넣을 수 있습니다. <machineKey> 요소는 애플리케이션의 루트에 있는 Web.config 파일에서만 유효하며 하위 폴더 수준에서는 유효하지 않습니다.
<configuration>
<system.web>
<machineKey ... />
</system.web>
</configuration>
지원되는 알고리즘의 전체 목록은 Windows PowerShell 프롬프트에서 도움말 Generate-MachineKey 실행합니다.
부록 B: 자동 생성된 키를 유지하도록 레지스트리 프로비전
기본적으로 ASP이기 때문입니다. NET 자동 생성 키는 HKCU 레지스트리에 유지되며, 사용자 프로필이 IIS 작업자 프로세스에 로드되지 않은 다음 애플리케이션 풀이 재활용되면 이러한 키가 손실될 수 있습니다. 이 시나리오는 표준 Windows 사용자 계정으로 애플리케이션 풀을 실행하는 공유 호스팅 공급자에 영향을 줄 수 있습니다.
이 상황을 해결하기 위해 ASP.NET HKCU 레지스트리 대신 HKLM 레지스트리에서 자동 생성된 키를 유지할 수 있습니다. 이 작업은 일반적으로 aspnet_regiis 유틸리티를 사용하여 수행됩니다("해결 방법 2a: aspnet_regiis 유틸리티 사용" 섹션의 지침 참조). 그러나 이 유틸리티를 실행하지 않으려는 관리자의 경우 다음 Windows PowerShell 스크립트를 대신 사용할 수 있습니다.
# 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)
}
}
}
다음 예제에서는 사용자 example@contoso.com 로 실행되는 애플리케이션 풀에 적절한 HKLM 레지스트리 항목을 프로비전하는 방법을 보여 줍니다(Windows 사용자 계정의 UPN임). 이 애플리케이션 풀은 CLR v2.0(ASP.NET 2.0 또는 3.5)을 실행하는 32비트 애플리케이션 풀입니다.
PS> Provision-AutoGenKeys -FrameworkVersion 2.0 -Architecture 32 -UPN "example@contoso.com"
대신 애플리케이션 풀이 CLR v4.0(ASP.NET 4.0 또는 4.5)을 실행하는 64비트 애플리케이션 풀인 경우 명령은 다음과 같습니다.
PS> Provision-AutoGenKeys -FrameworkVersion 4.0 -Architecture 64 -UPN "example@contoso.com"
자동 생성된 키가 HKLM에 저장되더라도 각 사용자 계정의 비밀 암호화 자료를 보유하는 레지스트리 하위 키는 다른 사용자 계정에서 암호화 자료를 읽을 수 없도록 ACL(액세스 제어 목록)에 추가됩니다.
부록 C: 구성 파일에서 <machineKey> 요소 암호화
서버 관리자는 machineKey> 키 자료와 같은 매우 중요한 정보가 구성 파일에서 <일반 텍스트 형식이 되도록 원하지 않을 수 있습니다. 이 경우 관리자는 "보호된 구성"이라고 하는 .NET Framework 기능을 활용하기로 결정할 수 있습니다. 이 기능을 사용하면 .config 파일의 특정 섹션을 암호화할 수 있습니다. 이러한 구성 파일의 내용이 공개되면 이러한 섹션의 콘텐츠는 여전히 비밀로 유지됩니다.
MSDN 웹 사이트에서 보호된 구성 에 대한 간략한 개요를 찾을 수 있습니다. 또한 Web.config 파일의 <connectionStrings> 및 <machineKey> 요소를 보호하는 방법에 대한 자습서도 포함되어 있습니다.