'2006/04/23'에 해당되는 글 12건

  1. 2006/04/23 [연재] 8. 보안 요청 by dalbong2
  2. 2006/04/23 [연재] 7. 보안 정책 배포 by dalbong2
  3. 2006/04/23 [연재] 6. 보안 정책 설정 예 by dalbong2
  4. 2006/04/23 [연재] 5. 보안 설정 편집 by dalbong2
  5. 2006/04/23 [연재] 4. 보안 정책(Security Policies) by dalbong2
  6. 2006/04/23 [연재] 3. 증거(evidence) by dalbong2
  7. 2006/04/23 [연재] 2. 보안 정책 평가( 권한 풀이)프로세스 by dalbong2 (1)
  8. 2006/04/23 [연재] 1. CAS(Code Access Security)란? by dalbong2 (1)
  9. 2006/04/23 AllowPartiallyTrustedCallers 어트리뷰트 by dalbong2
  10. 2006/04/23 Introduction to Code Signing by dalbong2
  11. 2006/04/23 GAC에 있는 어셈블리는 FullTrust권한을 부여하나? by dalbong2
  12. 2006/04/23 구성 섹션 암/복호화 by dalbong2

8. 보안 요청

보호된 리소스를 직접 액세스하는 코드를 작성하거나 이러한 액세스가 호출자에게 노출되는 경우, 호출하는 코드(어셈블리)에 권한이 있는지를 확인하는 요청을 작성할 수 있다. 호출자에 의한 호출이 실제로 수행되기 전에 이런 요청에 대한 권한 체크를 먼저 통과해야 한다.  이런 권한 요청은 어트리뷰트를 사용한 선언적인 방법을 사용할 수도 있고 또는 메소드를 통해서 프로그램적 요청을 사용할 수 있다.
대부분의 .NET Framework 클래스에는 자신과 연결된 요청이 이미 있으므로 보호된 리소스에 액세스하는 클래스를 사용할 때마다 요청을 추가할 필요가 없다. 예를 들어, StreamWriter 클래스는 열릴 때마다 자동으로 FileIOPermission에 대한 보안 요청을 한다. StreamWriter 클래스를 사용할 때 FileIOPermission을 요청하면 중복된 비효율적인 스택 워크가 발생한다. 사용자 지정 리소스를 보호하기위해서 개발자는 사용자 지정 권한을 요구하는 요청을 사용해야 한다.
여기서는 자원을 보호하기 위해서 코드상에서 특정 권한을 요청할 수 있는 메소드들을 소개한다. 그러나 이 메소드들을 이해하기 위해서는 StackWalk( 호출스택) 개념이 필요하다

■ StackWalk(호출 스택)

현재 비관리형 코드에 접근하려는 메소드 AccessUnmanagedCode()가 있다고 하자. 어셈블리에 대한 권한 체크는 이 메소드가 있는 어셈블리에 대해서만 수행되는 것이 아니다. 만약 AccessUnmanagedCode()가 다른 어셈블리에 있는 코드에서 호출되고 있다면 그 어셈블리에 대한 권한도 체크를 한다. 이것은 StackWalk라는 개념의 기술을 통해서 가능하다.
StackWalk라는 것은 말 그대로 풀이해본다면 "현재까지의 걸어온 자취 즉 어셈블리의 호출을 누적해놓은 것"이다. 그리고 자취의 누적 방향은 위에서 아래 방향으로 쌓여 간다고 상상하면 된다. 그림을 보자.

StackWalk 개념(클릭을 하면 선명한 그림이 뜹니다.)

그림처럼 Demand()(뒤에서 설명한다)라는 메소드를 통해서 해당 권한이 assembly3.dll에 부여되었는지를 체크 하게 되면 현재 어셈블리에서부터 차례로 StackWalk를 올라가면서 주어진 권한을 어셈블리별로 체크하게 된다. StackWalk 상의 모든 어셈블리가 권한 체크를 통과해야만 Demand() 이후의 코드가 실행될 수 있는 것이다.

■ Demand() 메소드

어셈블리 권한 풀이기(permission  resolver)는 대부분의 시간은 그냥 잠든(?)상태에 있다. 이것이 작동을 하는 경우는 어셈블리가 로딩되는 경우 CLR에 의해서 잠에서 깨어난다. 또한 코드상에서 권한 풀이기를 직접 깨울 수도 있다. 어떤 어셈블리가 보호를 받는 자원에 접근하려고 할 때 자신(또는 자신을 호출한 어셈블리)이 적절한 권한을 부여 받았는지를 확인해 볼 수 있다. 이런 권한 체크에, IPermission에 정의되어 있고 CodeAccessPermission에서 구현하고 있는 Demand() 메소드를 사용할 수 있다. 다음 예제는 SecurityPermission을 사용해서 체크할 권한을 지정하고 있는데, 이 클래스는 CodeAccessPermission 클래스를 상속하고 있다.

using System.Security;
using System.Security.Permissions;


void AccessUnmanagedCode()
{
  //비관리형 코드에 접근하는데 필요한 권한을 체크하기 위해서
  //필요한 권한 객체를 생성한다.
  SecurityPermissionFlag flag = SecurityPermissionFlag.UnmanagedCode;
  SecurityPermission perm = new SecurityPermission(flag);
 
  try
  {
  perm.Demand();
  }
  catch( SecurityException)
  {
  return;
  }
 
  //비관리형 코드에 접근
  …
}

AccessUnmanagedCode() 메소드는 비관리형 코드로의 접근을 시뮬레이션하고 있다. 권한 체크를 하려면 우선 적절한 권한(permission)객체를 생성해야 한다. 이 코드는 비관리형 코드(UnmanagedCode)에 대해 접근할 수 있는 권한이 있는지를 체크할 수 있는 권한 객체 SecurityPermission를 생성하고 있다. SecurityPermission 생성자가 받을 수 있는 SecurityPermissionFlg 열거형에는 다른 값들도 정의하고 있다.

System.Security.Permissions
{
  public enum SecurityPermissionFlag
  {
  AllFlags, Assertion, BindingRedirects, ControlAppDomain,
  ControlDomainPolicy, ControlEvidence, ControlPolicy,
  ControlPrincipal, ControlThread, Execution, Infrastructure,
  NoFlags, RemotingConfiguration, SerializationFormatter,
  SkipVerification, UnmanagedCode
  }
}

이 열거형들이 생성한 권한 객체는 어떤 내용의 권한을 체크할 수 있는지에 대한 내용은 MSDN을 참고하라.

권한 체크에 필요한 SecurityPermission객체가 생성되면 이제 그것의 Demand() 메소드를 호출하면 된다. 만약 현재 어셈블리가 해당 권한(비관리형 코드 호출 권한)을 가지고 있지 않다면 SecurityException  예외를 발생시킨다.

Demand() 메소드에 대해서 착각하지 말 것은, Demand()를 호출한다는 것은 "특정 권한을 요구하는 것이 아니다"것이 아니라 현재 어셈블리에 "특정 권한이 있는지 체크하는"것이다. 어셈블리의 코드가 실행될때쯤이면 실행되고 있는 컴퓨터의 보안 정책에 따랏 이미 사용 가능한 권한은 확정된다. 그리고 그 권한의 범위내에서만 실행될 수 있는 것이다.

Demand()를 사용하면 실행되고 있는 현재 컴퓨터의 보안 정책에 따라 몇가지로 행동하는 코드를 작성할 수 있다는 것이다. Demand() 메소드는 StackWalk를 통해서 호출하고 있는 모든 어셈블리들의 권한도 함께 체크한다.

■ Assert() 메소드

그러나 현재의 어셈블리가 충분한 권한을 가지고 있다면 StackWalk상에서 이전 어셈블리의 권한과는 상관없이 보호된 자원에 접근하려는 메소드가 실행될 수 있는 방법이 있다. 현재 어셈블리가 Assert() 메소드를 사용하여 권한을 체크하면 된다.

Assert() 권한 체크

Assert() 메소드는 StackWalk상에서 이전의 어셈블리에 대해서는 해당 권한을 부여하는 능력을 가지고 있다. 사실 권한 부여라기보다는 권한 체크 자체를 멈춘다.
그러나 현재 어셈블리가 해당 권한을 가졌는지를 먼저 체크한다. 즉 현재 어셈블리가 비관리형 코드를 호출할 수 있는 권한이 있는지를 체크한다. 자신도 가지고 있지 않은 권한에 대해 이전 어셈블리에 대해서 해당 권한에 대한 체크를 하지 말아달라고 요청하는 것은 받아 들여지지 않는다. 또한 현재 어셈블리가 Assert() 메소드를 호출할 만한 권한이 있는지도 체크한다. 비관리형 코드를 호출할 수 있는 권한이 있다는 것과, StackWalk상의 이전 어셈블리에 대해서도 그 권한 체크를 멈춰달라고 요청할 수 있는 권한은 다른 것이다. 다음은 이전에 Demand() 메소드에서 봤던 예제 코드에서 메소드만 Assert()로 변경했다.

using System.Security;
using System.Security.Permissions;


void AccessUnmanagedCode()
{
  //비관리형 코드에 접근하는데 필요한 권한을 체크하기 위해서
  //필요한 권한 객체를 생성한다.
  SecurityPermissionFlag flag = SecurityPermissionFlag.UnmanagedCode;
  SecurityPermission perm = new SecurityPermission(flag);
 
  try
  {
  perm.Assert();
  }
  catch( SecurityException)
  {
  return;
  }
 
  //비관리형 코드에 접근
  …
}

현재 어셈블리에 비관리형 코드를 호출할 수 있는 권한과 Assert() 메소드를 호출할 수 있는 권한이 있다면 예를 들어 FullTrust 권한 집합을 부여받은 어셈블리라면 위 Assert() 메소드는 효력을 발휘해서 StackWalk상의 이전 어셈블리에도 비관리형 코드에 접근할 수 있는 권한이 부여되는 효과가 발휘될 수 있다.

■ 기타 자원을 보호하기 위한 권한 요청 메소드들은 여러가지 있다. CodeAccessPermition 클래스를 참고하라.

참조 문서

ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.ko/
dv_fxsecurity/html/1d072877-ad4c-4d2c-8544-4b2502cb1f37.htm(msdn 한글)

http://msdn.microsoft.com/library/default.asp?url=/library/
en-us/cpguide/html/cpconCodeAccessSecurity.asp(영문
)

'개발 > Security' 카테고리의 다른 글

[연재] 7. 보안 정책 배포  (0) 2006/04/23
[연재] 6. 보안 정책 설정 예  (0) 2006/04/23
[연재] 8. 보안 요청  (0) 2006/04/23
[연재] 7. 보안 정책 배포  (0) 2006/04/23
[연재] 6. 보안 정책 설정 예  (0) 2006/04/23
[연재] 5. 보안 설정 편집  (0) 2006/04/23
Posted by dalbong2

7. 보안 정책 배포

지금까지의 과정, 권한 그룹 생성, 코드 그룹 생성 및 세부 사항 편집은 모두 프로그램적으로도 가능하다. 따라서 클라이언트 보안을 설정하는 exe 프로그램을 제작해서 사용자들에게 배포하면 된다. 그러자면 CAS와 관련한 API를 숙지하고 있어야 할 것이다.
그러나 관리 툴은 그보다 간단한 배포 방법을 제공해주고 있다. 이 방법을 사용하면 보안 편집 툴로 편집한 내용을 .msi 파일로 자동 생성해준다. 이 .msi 파일을 사용자들에게 배포만 하면 된다.

관리 툴을 이용한 보안 정책 배포 #1

런타임 보안 정책(오른쪽 클릭)->배포 패키지 만들기…를 선택한다.

관리 툴을 이용한 보안 정책 배포 #2

이 화면에서 배포할 보안 정책 수준을 선택할 수 있다. 그리고 .msi 파일명을 입력하고 마치면 배포 파일 생성이 완료된다.
이 .msi 파일을 클라이언트 컴퓨터에서 실행시키면 보안 설정이 변경된다.

'개발 > Security' 카테고리의 다른 글

[연재] 8. 보안 요청  (0) 2006/04/23
[연재] 6. 보안 정책 설정 예  (0) 2006/04/23
[연재] 7. 보안 정책 배포  (0) 2006/04/23
[연재] 8. 보안 요청  (0) 2006/04/23
[연재] 6. 보안 정책 설정 예  (0) 2006/04/23
[연재] 5. 보안 설정 편집  (0) 2006/04/23
Posted by dalbong2

6. 보안 정책 설정 예

다음은 관리툴을 사용해서 보안 정책을 배포하는 예제를 보겠다. 이 보안 정책에서는 부모와 자식, 2 계층 구조의 코드 그룹을 생성해서 권한 집합을 확대하는 방법을 보이겠다. 그리고 앞에서 생략한 사용자가 직접 권한 집합을 만드는 예도 더불어 본다.

■ 권한 집합 생성

먼저 코드그룹에서 사용할 권한 집합을 "SCPermissionSet'이라는 이름으로 미리 하나 만들어두자. 집합을 새로 생성하려면 권한에 대한 자세한 내용을 알고 있어야 한다. 그러나 현실적으로 엔터프라이즈 애플리케이션을 개발하는 개발자들이 권한 집합을 생성하거나 편집하면서 개발할 시간은 거의 없다. 따라서 개발자시에는 주로 이미 만들어진 FullTrust 권한 집합을 사용하는 것이 보통이다.

권한 집합 생성 #1

생성할 권한 집합의 이름을 입력한다. 다음을 클릭하면 권한 집합에 포함될 수 있는 가능한 모든 권한이 출력된다.

권한 집합 생성 #2

기본적으로 출력되는 권한들 외에도 다음 인터페이스를 구현해서 사용자가 직접 정의해서 추가할 수도 있다.

namespace System.Security
{
  public interface IPermission
  {
   IPermission Union(IPermission rhs);
   IPermission Intersect(IPermission rhs);
   bool        IsSubsetOf(IPermission rhs);
   IPermission Copy();
   void        Demand();
  }
}

그러나 달봉이는 아직 권한을 확장해 본 경험이 없다. 자세한 내용은 다른 문서를 참고하라.

사용 가능한 권한을 선택해서 추가를 하면 상세 권한을 설정하는 창이 뜨는데, 적당히 선택하고 나면 그림처럼 선택한 권한이 권한 집합에 할당된 것으로 나타난다. 마침을 클릭하면 새로운 권한 집합이 생성된다.

권한 집합 생성 #3

■ 코드 그룹 생성

이제 이 권한 집합을 부여할 코드 그룹을 생성한다. 새로운 코드 그룹에 대한 속성은 다음과 같다.

정책 레벨 : 컴퓨터 정책
부모 그룹 : All_Code
코드그룹명 : SmartClientCodeGroup
멤버조건 : URL = "http://www.dalbong2/*"
권한집합 : SCPermissionSet

생성된 권한 집합 부여

코드 그룹에 권한 집합을 부여할 때 기존의 권한 집합 목록을 보면 앞에서 생성한 권한 집합 "SCPermissionSet"도 포함되어 있다. 이것을 선택하면 된다.

부모 코드 그룹 추가 완료

■ 자식 코드 그룹 생성

이제 "SmartClientCodeGroup" 코드그룹의 자식 그룹을 하나 더 생성하자.

부모 그룹 : SmartClientCodeGroup
코드그룹명 : "SmartClientStrongNamed"
멤버조건 : 강력한 이름 = "공개키값"
권한집합 : FullTrust

다음은 자식 코드 그룹까지 생성한 모습이다.

공개키 조건값 입력

계층 구조의 코드 그룹

코드 그룹의 계층 구조는 어셈블리에 새로운 권한을 부여할 수 있는 방법이라고 앞에서 말했다. 만약 어떤 어셈블리의 CODEBASE URL이 "http://www.dalbong2.net/"를 포함하고 있다면 "SmartClientCodeGroup"그룹으로 분류되어 일단 권한 집합 "SCPermissionSet"에 포함되어 있는 권한들을 부여받게 된다. 그리고 "SmartClientCodeGroup"에 포함되는 어셈블리들 중에서 공개키가 "SmartClientStrongNamed" 그룹의 조건 값과 일치한다면 "FullTrust" 권한 집합에 매핑이 되어 모든 권한을 부여받게 된다. 이렇게 코드 그룹의 계층 구조를 통해서 좀 더 세밀한 권한 구조를 만들 수도 있다.

'개발 > Security' 카테고리의 다른 글

[연재] 8. 보안 요청  (0) 2006/04/23
[연재] 7. 보안 정책 배포  (0) 2006/04/23
[연재] 6. 보안 정책 설정 예  (0) 2006/04/23
[연재] 8. 보안 요청  (0) 2006/04/23
[연재] 7. 보안 정책 배포  (0) 2006/04/23
[연재] 5. 보안 설정 편집  (0) 2006/04/23
Posted by dalbong2

5. 보안 설정 편집

이제 개념적인 내용을 알았으니 PC의 보안 설정을 편집하는 방법을 알아보자.이곳에서는 어셈블리가 실행될 컴퓨터에 코드 그룹을 생성하고 그룹에 권한을 매핑하는 작업을 권한 관리 툴을 이용하는 방법을 보여준다. 툴을 사용해서 편집한 보안 내용은 .config 파일에 저장될 것이고 어셈블리가 로딩될 때 정책 평가기에 의해서 해석되어서 어셈블리에 설정된 권한을 부여할 것이다.
앞에서 이미 개념은 알았으니 툴의 사용 화면 캡쳐와 간단한 설명으로 쉽게 넘어갈 수 있으리라 본다. 엔터프라이즈, 컴퓨터, 사용자, 응용 프로그램 레벨별로 보안 설정이 가능하나 여기서는 주로 사용되는 컴퓨터 레벨의 보안 정책을 구성해보겠다. 다른 레벨의 정책도 동일하게 방법으로 구성될 수 있다. 순서는 간단하다. 다음 순으로 진행된다.
코드 그룹 생성
멤버 조건( 증거에 대한 조건) 입력
코드 그룹에 권한 집합 매핑
관리도구-> Microsoft .NET Framework 2.0 구성 메뉴를 통해서 .NET 설정 관리 툴을 실행시키자.
 

.NET 설정관리 툴 시작 화면

.NET 설정 관리 툴을 시작해서 런타임 보안 정책->컴퓨터->코드 그룹->All_Code를 선택한 화면이다. 기본적으로 생성되어 있는 코드 그룹이 있다.

■ 코드 그룹 생성
All_Code(오른쪽 클릭)->새로만들기…를 선택하면 다음 창이 뜬다.

 

코드 그룹 생성


적절한 코드 그룹 이름을 넣고 다음을 클릭한다. 달봉이는 "SampleGroup"라는 이름의 그룹을 생성할 것이다

■ 멤버 조건 입력
다음은 멤버 조건을 입력하는 화면이다. 멤버 조건이란 코드 그룹("SampleGroup")으로 분류되기 위한 증거들의 조건을 말한다.
 

멤버 조건 입력 #1

멤버 조건 입력화면이 뜨면 기본적으로 [All Code]조건이 선택되어 있다. 목록을 출력해보면 기본 증거에 해당하는 8가지 조건이 모두 출력된다.

 

멤버 조건 입력 #2


목록에서 특정 조건을 선택하면 조건에 따라 적절한 값을 입력할 수 있는 입력화면이 아래 공간에 출력된다.

멤버 조건 입력 #3

그림에서는 URL 조건 형식을 선택한 경우에 출력된 입력 화면을 보여주고 있다. 입력란에 달봉이는 "http://www.dalbong2.net/*"라고 입력했다. 즉 어셈블리의 CODEBASE URL값이 "http://www.dalbong2.net/"로 시작하는 모든 어셈블리에 권한을 적용하겠다는 의미다.
다른 조건 형식을 선택해보면 조건 형식에 따라 적절한 값을 입력할 수 있는 화면이 나타난다.  

멤버 조건 입력 #4


강력한 이름을 선택하면 공개키를 필수적으로 입력하고, 선택적으로 어셈블리 이름과 버전을 입력할 수 있는 화면이 출력된다. 가져오기 버튼을 클릭해서 해당 어셈블리를 선택하면 공개키와 이름, 버전을 자동으로 입력해준다. 공개키는 "sn.exe -Tp 어셈블리파일"을 통해서도 구할 수 있다. 이름과 버전의 체크박스를 선택하지 않으면 이름과 버전은 조건값에서 생략된다.

■ 권한 집합 할당

권한 집합 선택
멤버 조건을 입력한 후 다음을 선택하면 그림처럼 코드 그룹에 권한 집합을 매핑할 수 있는 화면이 출력된다. 기본적으로 정의되어 있는 권한 집합을 선택할 수도 있고, 새 권한 집합을 만들겠다고 선택할 수도 있다. 기존 권한 집합을 선택하겠다면 다음을 클릭해서 바로 작업을 마칠 수 있다.
직접 권한 그룹을 생성하는 것도 어렵지는 않다. 관리툴->런타임 보안 정책->컴퓨터->권한 집합(오른쪽 클릭)->새로 만들기… 를 통해서 가능하다. 권한 그룹을 직접 생성하는 것은 다음 예제에서 보겠다.
지금까지 코드 그룹을 생성하고 멤버 조건을 입력하고 권한 집합을 매핑하는 것까지 해서 컴퓨터 레벨의 새로운 보안 정책을 마련했다. 관리자가 보안 설정을 끝내고 저장을 하면 결과는 .config 파일에 XML로 저장될 것이다. 이제 어셈블리가 로딩되면, 권한 풀이기는 어셈블리가 제시할 수 있는 증거들을 근거로 해서 어셈블리가 어느 코드 그룹에 속하는가를 정책 파일을 해석해서 확인한다. 그리고 그 그룹에 부연된 권한을 어셈블리에 부여한다.

Posted by dalbong2

4. 보안 정책(security policies)
증거들은 그 자체만으로는 의미가 없고 PC에 설정된 보안 정책을 평가해서 그 증거들에 어떤 권한을 부여되는가 즉 어셈블리에 어떤 권한이 부여되는가에 따라서 어셈블리가 로딩도 될 수 있고 코드를 정상적으로 실행할 수 있는 가도 결정된다.
각 PC의 보안 정책은 .config 파일에 저장된다. 이 파일에는 어셈블리의 증거별 권한 집합이 정의되어 있다. 각 PC의 보안정책에는 “이 PC에서는 어떤 증거에 대해서는 어떤 권한을 부여하겠다”는 정책이 표현되어 있는 것이다. 보안 정책 파일은 사용자(관리자, 개발자)가 편집해서 적절한 보안 정책을 PC에 적용할 수 있다.  .NET의 SDK와 함께 제공되는 구성 편집 툴이 있는데, 이것을 사용하면 쉽게 보안 정책을 편집할 수 있다. 또한 기존의 보안 내용을 MS 인스톨러 프로그램 MSI으로 쉽게 다른 PC를 설정할 수도 있다. 보안 정책 편집에 대해서는 뒤에 다루겠다.
그러나 보안 정책은 하나의 파일에 정의되어 있지는 않다. 하나의 어셈블리에 적용될 수 있는 보안 정책 파일은 4개의 레벨로 구분되어 각 레벨별 정책을 담고 있는 .config 파일이 있다. 

보안 정책 레벨

사용자별로 보안 정책을 설정할 수 있다는 것은, 현재 로그인한 사용자에 따라서 어떤 어셈블리는 로딩될 수도 있고 아니면 보안 예외가 발생할 수 있다는 것이다. 마찬가지로 컴퓨터레벨의 보안 정책이 있다는 얘기는 어떤 컴퓨터에서 문제없이 실행되던 어셈블리가 다른 컴퓨터에서는 보안 문제가 일어날 수 있다는 것이다.
보안 정책 레벨은 이렇게 4가지 일 수 있다. 엔터프라이즈 레벨의 정책은 AD서버(Active Directory서버)에 등록된 컴퓨터들별로 보안 정책을 달리할 수 있다는 것이고 마찬가지로  컴퓨터별, 사용자별, 애플리케이션별로 정책을 달리 할 수 있다는 것이다. 보안정책 레벨은 .NET의 System.Security.PolicyLevelType 열거형으로 정의되어 있다.

namespace System.Security
{
  public enum PolicyLevelType {
  User,
  Machine,
  Enterprise,
  AppDomain
  }
}


기본적으로 AD서버 레벨의 권한설정(enterprisesec.config)에서는 모든 어셈블리에 FullTrust 권한을 부여한다. 그리고 컴퓨터 레벨의 설정(security.config)에서는 GAC에 등록된 어셈블리에만 모든 권한을 부여한다. 이 정책은 레벨 순서대로 적용이 된다. 즉 엔터프라이즈 정책->컴퓨터 정책->사용자정책->애플리케이션 정책 순으로 적용이 된다.
근데, 만약 이 4가지 레벨의 정책이 특정 권한에 대한 설정 내용을 가지고 있다면 어떻게 되는가?

레벨별 다른 권한 부여 예
예를 들어 엔터프라이즈 레벨의 보안 설정에서는 모든 어셈블리에 대해서 로컬 파일에 대해서 읽기 쓰기 권한을 부여하고 있다. 그러나 그림에서 처럼 그 다음 레벨의 컴퓨터 정책에서는 Url 증거가 "http://Sever/*"인 즉 이 경로에서 받은 어셈블리에 대해서는 로컬 파일에 대해 읽기 권한만을 부여한다. 그럼 해당 어셈블리에 대한 권한은 어떻게 부여되어야 할까? 그렇다. 읽기 권한만이 부여될 것이다.
이처럼 만약 어떤 어셈블리가 이 4가지 정책에 모두 연관될 수 있다면, 즉 어떤 어셈블리가 있는데, 이 어셈블리가 실행되는 컴퓨터가 AD서버에 등록되어 있고 그리고 이 애플케이션을 실행하기위해서 로그인한 사용자도 이 어셈블리에 대해 어떤 보안 설정을 해뒀고 그리고 애플리케이션 레벨에서도 어떤 보안 설정을 해 둔 경우라면 결과는 다음 그림과 같다.
그림 6 보안 정책의 중첩
그림은 적용 가능한 모든 정책의 교집합에 해당하는 권한이 어셈블리에 부여되는 최종 권한이 된다는 것을 보여준다.
보안 정책 파일에는 3가지의 주요 내용 설정이 있다: 코드그룹(Code Group), 멤버 조건(Member Condition), 권한 그룹(Permision Set).
 

보안정책 적용 과정


코드그룹, 멤버조건, 권한 집합를 갖는 구조가 다른 레벨의 보안정책에도 동일하게 적용될 수 있으나 그림에서는 컴퓨터 정책 레벨의 보안 정책을 예로 보여주고 있다.
각 보안 정책 레벨별로 코드 그룹(Code Group)이라는 것이 여러 개 정의될 수 있다. 코드 그룹은 어셈블리들이 모임의 멤버가 되는 것이다. 이 코드 그룹은 권한을 부여하는 대상의 단위가 된다.
코드 그룹에는 두 가지 중요한 속성이 있다 : 멤버조건(Member Condition), 권한 집합(Permission Set).
관리자는 먼저 코드 그룹을 생성할 수 있고, 그곳에 가입할 수 있는 멤버(즉 어셈블리)들에 대한 조건을 정의할 수 있다. 멤버 조건(Member Condition)이란 어셈블리의 증거들에 대한 조건이다. 즉 "어떤 증거를 가지고 있는 멤버만이 이 코드그룹에 가입(?)된다."라는 의미이다. .NET에는 기본적으로 다음과 같은 멤버 조건을 가지고 있다: 사이트, Url, Zone, ApplicaionDirectory, 강력한 이름, 게시자, 해시, GAC. 즉 "이 코드 그룹에는 Url(사이트, Zone…)증거로 특정 값을 가지고 있는 어셈블리가 멤버로 가입될 수 있다"는 의미가 된다.
코드 그룹에는 또한 권한 집합(permission set) 매핑된다. 원어 그대로 보면 어셈블리에게 허용되는 권한(permission)들의 집합(set)이다. 권한 집합에는 여러 개의 권한들이 포함될 수 있는데, 즉 코드 그룹에 부여되는 권한은 집합 단위로 적용되는 것이다. 다음은 기본적으로 .NET에 정의되어 있는 권한들을 보여주고 있다.
 

.NET 권한들과 보호되는 자원들

다음 표는 기본적으로 정의되어 있는 권한 집합을 보여주고 있고, 그 권한 그룹에는 어떤 권한들이 있는지도 보여주고 있다.

.NET 기본 권한 그룹

지금까지의 개념을 이야기로 풀이해보면 이렇다: "어떤 코드 그룹에는 특정 증거 조건을 갖는 멤버들만이 가입할 수 있으며 그 그룹에 포함되게 되면 어떤 권한들을 가질 수 있다". 각 어셈블리들에 대한 증거 조건을 판단하고 코드 그룹의 멤버로서의 적합 여부를 평가하는 것이 바로 보안 평가기(policy evaluator, 권한 풀이기)이다.
하나의 어셈블리가 여러 개의 코드그룹에 속하는 경우도 있을 것이다. 이런 경우 권한 풀이기는 어떻게 처리할까? 기본적으로 이런 경우는 이것은 합집합(union)의 개념이다. 예를 들어 사용자가 정의한 "SampleGroup"이라는 코드 그룹에도 속하고 기본 코드 그룹 LocalIntranet_Zone에도 속 한다면 두 그룹에 부여된 모든 권한을 가질 수 있다.

동일 정책 레벨상의 코드 그룹들의 권한 합집합

코드 그룹은 자식 그룹을 포함할 수 있도록 되어 있어서, 그림과 같은 계층 구조로 될 수 있다. 코드 그룹이 계층 구조로 이뤄지면 어셈블리가 사용할 수 있는 권한에 대한 합집합의 개념이 자식 코드 집합으로 확장될 수 있다. 무슨 말인가 하면, 특정 어셈블리가 코드 그룹 A의 멤버 조건을 만족하면 B,C,D에 대한 멤버 조건도 체크한다. 만약 그룹 C에 대한 조건이 만족되면 C의 권한도 부여받고 다시 E,F 그룹에 대한 조건도 체크를 하게 된다.

코드그룹 계층구조

따라서 자식 그룹을 추가해서 계층구조를 만드는 방법을 이용해서 어셈블리에 새로운 권한 집합을 매핑시킬 수 있다.
코드 그룹, 멤버 조건, 권한, 권한 그룹 등은 모두 사용자 정의가 가능해서 원하는 대로 확장할 수 있는 개념들이다. 달봉이의 능력을 넘어서는 주제들로서 여기서는 다루지 않는다.
Posted by dalbong2

3. 증거(evidence)

권한 풀이기(permission resolver)는 어셈블리를 로딩하면서 그것에 대한 증거를 수집하게 된다. 이런 증거들은 .config 파일에 있을 수 있고(CODEBASE) 또는 어셈블리가 가지고 있는 메너페스트 등에도 있을 수 있다. 다음 그림은 .NET에서 사용하는 증거들을 “어디서 왔는가”에 사용되는 증거들, “누가 만들었는가”에 사용되는 증거들 그리고 기타 증거들로 분류해 놓고 있다.  

.NET의 7가지 증거(v2.0 기준)

.NET에서는 그림에 나타난 것처럼 기본적으로 8가지 증거를 확인한다. 어디서 왔는가? 누가 만들었는가?를 판단하는데 사용되는 증거들을 구분해서 보여주고 있다. 기타에 있는 해시값은 관리자가 어셈블리 파일을 배포한 이후 임의의 코드 변경(해킹)이 이뤄졌는가를 체크할 수 있는 증거이다. 하나의 어셈블리에 이 모든 증거가 부여되지는 않겠지만 몇 개가 동시에 부여될 수도 있다.

어셈블리 권한 풀이기는 어셈블리의 CODEBASE에 사용된 URL(http://, file://)을 통해서 어셈블리의 위치 기반의 증거(Url, Site, Zone)을 결정한다.
“Url” 증거는 CODEBASE  URL (http://호스트명/배포디렉토리/어셈블리명)을 통해서 바로 구할 수 있다. Site, Zone 증거도 URL에서 유추된다. Site 증거는 URL중에서 호스트 서버명 부분만을 말한다. CODEBASE URL이 http://www.example.com/assem.dll인 경우, 수집되는 “Site” 증거는 www.example.com이 된다. 만약 CODEBASE가 file:///C:/~ 형식이라면 Site증거는 없게 된다.
“Zone” 증거도 URL을 통해서 유추한다. CLR의 입장에서 보안과 관련해서는 세상을 5개의 영역으로 나눈다 : 내컴퓨터, 로컬 인트라넷, 인터넷, 신뢰할 수 있는 사이트, 신뢰할 수 없는 사이트. .NET에서는 System.Security.SecurityZone 열거형에 다음과 같이 정의하고 있다.

namespace System.Security
{
public enum SecurityZone
{
   MyComputer,
   Intranet,
   Trusted,
   Internet,
   Untrusted,
   NoZone = 0xFFFFFFFF
  }
}

로컬 파일 시스템에서 로딩된 모든 어셈블리는 MyComputer Zone에 속하게 된다. 그리고 원격 시스템에서 다운된 코드는 모두 IE 브라우저에서 구분하고 있는 영역을 기반으로 해서 결정된다.

IE 브라우저의 보안 영역 구분

IE 브라우저에서는 파일의 URL을 기반으로 해서 3영역, 로컬 인트라넷, 신뢰할 수 있는 사이트, 제한된 사이트를 정의한다. 그리고 이 3 영역에 포함되지 않는 모든 URL은 인터넷 영역에 포함된다. “로컬 인트라넷 영역”은 CODEBASE URL로, UNC 스타일의 URL( 예, \\server\dlls\assem.dll), DNS 스타일이나 IP 기반의 주소를 사용하지 않는 WINS 스타일의 HTTP URL( 예, http://서버명/apps/assem.dll, http://localhost/apps/assem.dll) 그리고 네트워크 공유 드라이브를 사용하는 URL( z:\apps\assem.dll)을 사용하는 어셈블리들이 이 영역에 포함된다. 사용자가 직접 이 영역에 포함되도록 사이트를 추가할 수도 있다.
IE 브라우저는 다시 “신뢰할 수 있는 사이트”와 “제한된 사이트” 영역을 정의하고 있다.  이 영역에는 사용자가 URL을 직접 추가하도록 해서 이 URL들에만 각각 적용되는 영역이다. URL이 앞의 어느 영역에도 적용되지 않으면 “인터넷 영역”으로 분리된다.
IE 브라우저에서 정의한 영역은 그대로 CAS 보안 영역에도 적용된다. 즉 브라우저에서 결정된 어셈블리에 대한 영역은 그대로 CAS의 보안 영역에 매핑되어서 어셈블리의 Zone 증거로 사용된다. 예를 들어, 어셈블리가 브라우저의 로컬 인트라넷 영역에 포함되었다면 이 어셈블리는 Zone 증거로 Intranet이 주어지게 된다.
“ApplicationDirectory” 증거는 애플리케이션의 베이스 디렉토리 값으로 결정된다. .NET2.0에서 새롭게 추가된 위치 기반의 증거로 “GAC”이 있는데, GAC에 등록된 어셈블리에 주어지는 증거이다. 지금까지 위치 기반의 증거들에 대해서 알아봤다.
위치 기반의 증거들외에도 .NET이 기본적으로 정의한 증거에는 누가 개발했는가를 알려주는 증거도 있다 : 강력한 이름(StrongName), 게시자(Publisher)
어셈블리의 4가지 이름 정보로 구성된 강력한 이름은 어셈블리의 메너페이스에서 구할 수 있다. 강력한 이름은 개발자 또는 이 어셈블리를 개발한 회사별로 고유한 이름이고 따라서 "어떤 이름을 갖는 어셈블리에게는 어떤 레벨의 권한을 부여하겠다"는 식의 보안 정책이 가능하다. 게시자(publisher) 증거도 마찬가지이다. 어셈블리는 공인 인증 기관에서 발급한 인증서에 대한 내용을 메너페스트에 디지털 서명으로 가지고 있을 수 있다. 이런 경우도 "어떤 인증 정보를 갖는 어셈블리에게는 어떤 권한을 부여하겠다"는 것이 가능하다.
마지막 증거, 해시(Hash)는 어셈블리 파일의 해시값으로서 어셈블리가 컴파일될때마다 변경될 수 있다. 어셈블리가 로딩되기 전에는 이 해시값이 없다. 로딩되면서 로더에 의해서 자동으로 어셈블리에 추가된다. 권한풀이기는 이 값을 증거로서 사용하는 것이다. 이것으로 증거들에 대한 이야기는 마치겠다.
이런 증거들을 근거로 해서 어셈블리에 주어질 권한을 계산해 내기 위해서는 PC마다 설정된 보안 정책이 있을 것이다. 이제 이 보안 정책에 대해서 알아본다.
Posted by dalbong2

2. 정책 평가 / 권한 부여 프로세스

어셈블리가 어디서 왔고, 누가 만들었는지에 대한 정보를 어셈블리의 증거(evidences)라고 한다. 이런 어셈블리가 제시하는 증거들을 근거로 해서 어셈블리가 부여받을 수 있는 권한 집합(permission set)을 결정하게 되는데, 이런 과정을 정책 평가(policy evaluation)라고 한다. 대신에 달봉이는 권한 풀이(permission resolving)라는 말로도 표현한다.

증거들을 근거로 해서 어셈블리의 권한을 결정할 수 있으려면, 증거별 권한(permission)을 평가, 부여할 수 있는 정책이 PC에 정의되어 있어야 할 것이다. 이런 정의를 보안 정책(security policy)라고 하며 보안 정책에 대한 내용은 .config 파일에 XML 포맷으로 담겨져 있다. 이런 보안 정책 파일에는 쉽게 말하면 "어느 URL에서 온 어셈블리에는 어떤 권한을 부여할 것이고 그리고 어떤 공개키를 갖는 어셈블리에는 어떤 권한을 부여할 것이다"등등의 내용이 들어 있다. 이런 정책 평가 구조를 나타내면 다음과 같을 것이다. 

증거와 보안정책

입력되는 어셈블리의 증거들과 보안정책을 바탕으로 해서 어셈블리의 권한을 결정하는 과정을 앞에서 말한 것처럼 어셈블리 이름풀이(assembly permission resolving)이라 했고, 이것을 담당하는 CLR의 시스템을 어셈블리 권한풀이기(permission resolver, 정책 평가기 policy evaluator)라고 부르겠다. 그림에서 권한 풀이기는 어셈블리들에 대한 증거들을 입력받아서 결과적으로 어셈블리에 대한 권한을 결과물로 내놓는 블랙박스로 표현하고 있다.

권한 풀이 과정을 다시 순차적으로 그려보면 다음과 같다.

어셈블리 권한풀이 과정

권한풀이 과정을 하나씩 알아가 보자.

Posted by dalbong2

1. CAS(Code Access Security)란?

스마트클라이언트 애플리케이션에서는 배포와 함께 가장 이슈로 떠오르는 문제가 바로 보안의 문제이다. 어셈블리가 외부로부터 다운되기 때문에 어떻게 외부 코드로부터 로컬 PC의 자원을 보호하느냐가 문제가 되는 것이다. 기존의 사용자 중심의 보안체계로는 이 경우를 대처할 수 없게 된다.

사용자 중심의 보안 체계라는 것은 사용자별로 계정이 있고 그 계정에 권한을 부여하는 방식이었다. 따라서 윈도우상에서 보안을 판단할때는 이 사용자(즉 이 계정)를 기반으로해서 현재의 프로세스를 실행시킬 수 있느냐 없느냐를 체크했다.

사용자 계정 중심의 보안 체계에서는 인터넷에서 프로그램을 다운, 설치를 사용자가 한번만 승인하게 되면 이 코드는 현재 로그인된 사용자의 계정 권한을 이어 받게 된다. 만약 로그인된 사용자 계정이 관리자 그룹에 속하는 계정이라면 이 프로그램은 무소불위의 권력을 갖게 된다. 중요 파일을 삭제하거나 중요 정보를 외부로 유출시킬 수도 있다. ( 이런 이유들 때문에 아무리 PC의 주인일지라도 사용자 계정을 하나 만들어서 관리자 계정이 아니라 사용자 계정으로 로그온해서 작업을 하도록 보안 전문가들은 권장하고 있는 것이다.)

그러나 .NET 프레임워크에서는 어셈블리 중심의 새로운 보안 체계가 도입된다. 이름하여 CAS(Code Access Security. 흔히 ‘카스’라 발음한다.)라고 한다. .NET의 CAS에서는 현재 로그온된 계정이 누구인지도 중요하지만, 이 코드가 어디에서 왔고 누가 만들었는지도 체크를 한다. 이런 정보들을 바탕으로 해서 CLR은 어셈블리의 권한을 결정하게 되고 그 어셈블리의 권한에 따라 어셈블리의 로딩여부 또는 실행여부가 결정된다. 동일한 어셈블리라 하더라도 이것이 어느 곳에서부터 왔느냐에 따라 그 권한이 달라질 수 있다. 예를 들어 인터넷에서 다운받아서 실행시키는 경우는 보안 에러가 발생하더라도 동일한 어셈블리를 로컬 PC로 복사해서 실행시키면 아무 문제없이 실행된다는 것이다. 요즘 같은 분산환경의 컴퓨팅 시기에는 애플리케이션에서 실행되는 코드가 어디로부터 어떻게 들어올지 미리 예측하기가 힘들다. 이러한 환경에서 CAS는 합리적인 보안체계라 아니 할 수 없다.

Posted by dalbong2
TAG CAS

로컬 PC 외부에서 들어오는 어셈블리는 로컬 PC의 어셈블리들과는 달리 권한에 있어서 제한을 받는다. 이렇게 완전한 권한을 부여받지 못한 어셈블리를 이름하여 부분적으로 신뢰를 받는 어셈블리(partially trusted assembly)라고 한다. FullTrust 권한을 부여받지 못했다면 Everything 권한 집합을 부여받은 어셈블리할지라도 부분적으로 신뢰를 받는 어셈블리에 속하게 된다.
.NET CLR은 기본적으로 강력한 이름의 어셈블리(strong named assembly)는 완전한 권한을 갖는 어셈블리만이 호출할 수 있도록 하고 있다. 그러나 강력한 이름의 어셈블리가 AllowPartiallyTrustedCallersAttribute(APTC) 어셈블리 어트리뷰트를 사용하게 되면 부분 신뢰의 어셈블리로부터의 호출도 허락하겠다는 의미인것이다.

--AssemblyInfo.cs

using System.Security;
[assembly:AllowPartiallyTrustedCallers]

GAC에 등록된 어셈블리가 이 어트리뷰트를 가지고 가지고 있다면 외부에서 들어온 어셈블리들도 GAC에 등록된 어셈블리를 사용할 수 있게 되는 것이다. APTC 어트리뷰트를 사용하려면 개발자는 있을 지도 모르는 보안문제에 대해서는 스스로가 모두 체크해야 한다. 그래서 필요하다면 클래스나 메소드 수준의 보안 요청을 해서 권한 체크를 해야 한다. 만약 중요한 자원에 대한 액세스를 포함하고 있는 어셈블리나 보안상 약점이 있는 어셈블리가 이 어트리뷰트를 포함하고 있다면 문제가 될 수도 있다. 그래서 .NET 프레임워크 1.0에 이 어트리뷰트의 추가 여부를 두고 가장 늦게까지 결정이 미뤄졌다고 한다. .NET 프레임워크 1.0 베타 버전에서는 아예 추가되지도 않았다고 한다.
.NET 어셈블리의 핵심 코드를 가지고 있는 어셈블리에서는 이 어트리뷰트를 사용하지 않고 있다. 부분 신뢰 환경의 애플리케이션을 작성할때는(애플리케이션에 FullTrust 권한을 부여했다면 상관없다), .NET 프레임워크의 어셈블리들중에서 APTC를 허용하는 어셈블리들을 확인하고 이 어셈블리들이 제공하는 기능의 범위내에서 애플리케이션을 작성해야 한다.

APTC 어셈블리 목록

웹 브라우저 임베딩 방식의스마트 클라이언트 애플리케이션을 제작할때는 <object>태그를 통해서 대상 어셈블리를 로딩하게 된다. 앞의 APTC 어셈블리 목록중에 ieexecremote.dll이라는 어셈블리가 있는데, 이 어셈블리가 <object>에 의해 최초 호출되는 어셈블리의 OnLoad() 호출하는 스택상에 존재한다. 따라서 <object>에 의해 호출되는 어셈블리는 APTC 어트리뷰트가 있어야 한다. 그리고 다시 이 어셈블리에 의해 참조되는 다른 어셈블리 또한 APTC가 표시되어야 한다는 것도 기억하길 바란다. 웹 페이지에서 태그<object>를 이용해서 어셈블리를 로딩하려고 할 때 대상 어셈블리는 약한 이름의 어셈블리(weakly named assembly)이던지 만약 어셈블리가 강력한 이름의 어셈블리(strongly named assembly)라면 AllowPartiallyTrustedCallersAttribute(APTC) 어트리뷰트를 추가해야 정상적인 로딩이 가능하다.
다시 한번 더 상기시키면, APTC 어트리뷰트는 강력한 이름의 어셈블리에만 적용된다. 약한 이름의 어셈블리는 이 어트리뷰트가 필요없다.

참조 문서

ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.ko/
dv_fxsecurity/html/dd66cd4c-b087-415f-9c3e-94e3a1835f74.htm(영문)

APTC 어셈블리 여부 확인 툴 제공
http://www.develop.com/technology/resourcedetail.aspx?id=843c6027-b697-469d-933b-014b61f7d500

Posted by dalbong2
TAG APTC
ClickOnce의 배포를 이야기하면서 Authenticode에 대한 이야기가 나와서 그 원리를 함 알아보려고 했다. 달봉이도 Authenticode에 대해서는 잘 모른다. 혹시라도 잘못된 곳이 있으면 사정없는 댓글에 대한 희망을 전한다.


Introduction to Code Signing 요약

■ 코드 사인(code singing) 소개

인터넷으로 파일 다운로드하는 경우, 두 종류의 보안 이슈가 발생한다.

1. 게시자의 신뢰성 확인(Ensuring authenticity)
- 누가 게시했나? 즉 게시한 사람은 믿을 수 있나?
2. 코드의 무결성 확인(Ensuring integrity)
- 게시 이후 코드(소프트웨어)는 변경되지 않았나?

Authenticode는 이런 이슈를 해결하기 위한 Microsoft에서 제시한 솔루션을 말한다.

■ Authenticode

Authenticode 자체는 사인이 된 코드를 만들어 내지 않는다. 단지 코드 사용자들에게 코드 게시자(publishers)가 신뢰할 수 있는 인증 기관의 인증을 받았는가를 알려줄 수 있는 메커니즘이다. Authenticode는 인터넷을 이용한 코드(소프트웨어)의 배포 및 다운로드에 참여하고 있는 코드 게시자 및 코드 사용자 모두에게 필요한 기술이다.

■ 코드의 변경 여부 확인- 디지털 사인(Digital Signatures) 

코드(데이터 또는 소프트웨어)를 배포할 때 사용자들에게 배포자가 누구인지를 알리고 싶을 때 사용하는 것이 디지털 사인이다. 디지털 사인은 데이터의 내용을 변경하지 않는다. 다만 데이터와 함께 배포될 수 있는 디지털 사인 문자열이 생성된다. 이 디지털 문자열과 데이터가 한 파일로 묶여서 배포될 수 있다.

디지털 서명은 "public-key 알고리듬"을 사용해서 생성된다. 이 알고리듬은 이름과는 달리 public / private 키 쌍을 사용한다.
Authenticode 기술에서는 private 키를 "서명"에 사용하고, 다시 "서명의 확인"에 public 키를 사용하게 된다. ( 이 한줄은 기본이 되어 있지 않은 달봉이를 끝까지 인내로서 대해주신 정성태님의 지극한 조언이 없었으면 나오지 못했을 말이다. 근데 잘 이해를 했는지는 모르겠다.  쯔읍 아휴~~허접덩이)

public-key 알고리듬을 응용한 Authenticode 서명(-_-;;) 데이터 소유자는 데이터를 public / private 키를 생성해서, public 키는 필요한 모든 사람들에게 공개한다. 특정 private 키로 서명을 하면 서명확인은 반드시 해당 public 키로 해야 한다.

Authenticode 의 프로세스를 요약하면 다음과 같다.
1. 파일의 해시(one-way hash)값을 계산한다.
2. 해시값은 private 키를 이용해서 암호화가 된 문자열(서명 문자열)을 만들어낸다.
3. 파일과 서명이 된 해시값, public 키를 배포한다.
4. 배포를 받은 클라이언트는 파일의 해시값을 구한다.
5. 클라이언트는 사인이 된 해시값을 public 키를 이용해서 다시 복호화해서 원래의 해시값을 구한다.
6. 클라이언트가 구한 두 해시값이 일치하면 코드는 배포 이후에 변경되지 않았다는 것을 알 수 있다.

■ 게시자의 신뢰여부 확인 - 인증서(Digital Certificates)

디지털 인증서(digital certificate)는 라는 것은 적절한 절차를 거쳐 신청자(게시자)의 신청을 심사한 후 인증 기관(Certification Authority, CA)이 발행한다. 실제의 디지털 인증서는 파일로 존재하는데, 이 파일의 구조에는 신청자 및 인증 기관에 대한 정보 등 여러 가지가 포함되어 있다. 다음 그림은 X.509 프로토콜의 인증서 구조를 나타내고 있다.

X.509타입의 인증서 구조

Version : 인증서 포맷을 규정하는 번호
Serial Number : CA의 고유한 번호
Algorithm Identifier : 인증서를 서명하기 위해서 사용된 알고리듬
Issuer : CA 명
Period of Validity : 인증서의 유효 기간 정보
Subject : 신청자명
Subject’s Public Key : 신청자의 public 키 정보
Signature : CA의 디지털 서명

디지털 인증서는 크게 신청자의 “신청정보”와 “인증 기관의 디지털 서명”으로 구성되어 있다. 인증 기관의 디지털 서명은 인증 기관의 private 키로 “신청정보”를 암호화한 문자열이다. 인증서를 사용하는 클라이언트측에서는 이 인증기관의 디지털 서명과 인증기관의 public 키를 이용하면, 인증서에 포함된 게시자의 public 키가 인증 기관이 인증서를 발행했던 그 신청자의 public 키인지를 확인할 수 있다.

인증서에 포함된 신청자의 public 키 검증
(클릭을 하면 선명한 화면이 보입니다.)

그림은 인증서에 포함된 신청자의 public 키가 실제로 인증 기관이 인증한 신청자의 public 키인지를 검증하는 프로세스를 그린 것이다. 점선 부분이 인증서를 사용하는 클라이언트측에서 수행되는 검증 작업을 나타낸다. 만약 신청자의 public 키를 포함하고 있는 “신청정보”의 해시값과 인증서에 포함된 인증기관의 서명과 인증기관의 public 키로 복호화된 해시값이 일치하면 신청 정보가 변경되지 않았다는 것이고 따라서 신청 정보에 포함된 신청자의 public 키도 변경되지 않았다는 것을 알 수 있다. 이것은 또한 디지털 인증서의 가장 중요한 목적중의 하나인 인증서에 포함된 게시자는 인증 기관의 인증을 받은 것으로 판단내릴 수 근거가 될 수 있다. 즉 인증서의 게시자를 신뢰할 수 있게 되는 근거가 될 수 있다.   

■ 정리

이제 정리를 하자면 다음 두 그림으로 요약될 수 있다.

서명 과정

이 그림은 게시자(인증서 소유자)가 파일(어셈블리 파일)에 서명을 하는 과정을 나타내고 있다. 그림을 보면 파일의 해시값(정확히는 파일 전체의 해시값이 아니라 “메시지 축약(message digest)에 대한 해시값)을 게시자의 private 키로 서명을 한다. 그리고 시그너쳐 문자열과 인증 기관으로부터 발급받은 디지털 인증서를 서명 툴들을 사용하면 최종적으로 원래의 파일 내용의 검증 작업에 필요한 정보들이 덧붙여진 모습의 파일이 그림처럼 생긴다. 이제 이 파일을 인터넷을 통해서 사용자들에게 배포하면 된다.

서명확인 과정

인터넷을 통해서 배포받은 파일에 대해서 클라이언트(브라우저)측에서 검증하는 절차를 나타내고 있다. 클라이언트측에서는 먼저 원래 파일의 데이터를 이용해서 계산한 해시값과 게시자의 public 키를 사용해서 복호화한 해시값을 비교해서 코드의 무결성을 검증한다. 코드 무결성 검증을 통과하면 인증서가 신뢰할 수 있는 기관에서 발행한 것인지를 확인하는 작업을 하게 된다. 이 모든 작업을 통과하면 파일은 게시 이후에 변경되지 않았고 또한 인증기관의 인증을 받은 신뢰할 수 있는 게시자가 그 파일을 배포했다는 것을 의미하게 된다.


참조문서

Introduction to Code Signing - msdn
http://msdn.microsoft.com/library/default.asp?url=/workshop/security/authcode/intro_authenticode.asp
Posted by dalbong2

v2.0의 CodeGroup의 멤버 조건을 보면 "GAC"이라는 것이 하나 더 추가되었다. 이것과 관련해서 잠시 정리해 두려 한다.

Q : GAC에 등록된 어셈블리는 항상 FullTrust 권한을 부여받을까?
A : 상황에 따라 다르다.

v1.X에서는 GAC에 등록된 어셈블리도 MyComputer 영역의 어셈블리도 간주해서 MyComputer 영역의 권한셋인 FullTrust 를 부여받았다. 그래서 MyComputer 코드 그룹의 권한을 변경하면 GAC에 등록된 어셈블리의 권한도 함께 변하게 되었다.
그러나 v2.0에서는 GacMembershipCondition을 추가하고 있다.

추가된 멤버 조건 : GAC

이 조건을 사용하면 GAC에 등록된 어셈블리는 MyComputer 영역의 권한셋과는 별도의 권한을 부여할 수 있다. 즉 MyComputer 코드 그룹에 FullTrust가 아닌 권한셋을 부여한다고 해도, GAC에 등록된 어셈블리는 계속해서 FullTrust 권한을 부여할 수 있다.

Posted by dalbong2
구성파일 (web.config) 암/복호화에 대한 포스트가 있어서 소개합니다.

ensimple.net
http://www.ensimple.net/enSimple/show.aspx?cnum=87&b_id=study_csharp&page=1

msdn
http://msdn2.microsoft.com/ko-kr/library/53tyfkaw.aspx
http://msdn2.microsoft.com/ko-kr/library/zhhddkxy.aspx
Posted by dalbong2