C# 어셈블리에 사인(Sign)은 왜 하는 것일까?

[제목] C# 어셈블리에 사인(Sign)은 왜 하는 것일까?

C# DLL (또는 EXE 파일) 어셈블리에 사인(Sign)은 왜 하는 것일까? 만약 사인하지 않는다면, 어떠한 제약사항이 있을까?

닷넷 어셈블리에 사인을 한다는 것은 해당 어셈블리의 특정 영역에 Digital Signature와 public key를 적는다는 것을 의미한다. 이 Digital Signature는 한 어셈블리의 내용이 다른 누구의 조작에 의해 변경되지 않았음을 보증하는 역할을 한다. 하나의 어셈블리는 하나 이상의 .NET 모듈로 구성되는데, 이 모듈들의 해시값에 기초하여 어셈블리의 변경을 방지하도록 Digital Signature를 CLR 메타데이타에 포함하게 된다. 이렇게 사인된 어셈블리 안의 코드 혹은 리소스 내용을 변경한다면, CLR로더는 에러를 발생시킨다.

Digital Signature는 Private/Public 키 메카니즘을 사용한다. Digital Signature를 생성하기 위해서는 Private 키를 사용하고 이 시그니쳐를 읽어 검증하기 위해서는 Public 키를 사용한다. 따라서 출시되는 사인된 DLL 컴포넌트는 CLR 메타데이타에 Digital Signature와 이를 검증할 수 있는 public key가 함께 들어 있다. 보통 한 회사의 어셈블리에 대해 하나의 private/public 키를 이용하는데, 특히 private key는 해당 회사의 Digital Signature를 생성할 수 있는 키이므로 특히 각별한 보안을 유지해야 한다.

C# 프로젝트를 빌드하면 디폴트로 사인되지 않은 어셈블리(Weak assembly)를 생성한다. 이렇게 생성된 DLL (또는 EXE) 파일의 메타데이타를 ILDASM.EXE (.NET SDK 유틸러티)으로 살펴보면, 해당 DLL은 public key를 갖고 있지 않음을 알 수 있다.

weak assmebly

이 DLL을 사인하기 위해서는 private/public 키가 필요한데, 이를 생성하기 위해 sn.exe라는 툴(.NET SDK)을 사용할 수 있다. 아래와 같이 sn의 -k 옵션을 사용하면 private/public key pair 를 갖는 키파일 key.snk를 생성해 준다.

C> sn -k key.snk

이 키를 프로젝트 속성의 Signing 탭에서 아래와 같이 지정하고 빌드하면, private 키를 이용해서 Digital Signature를 생성하여 출력 DLL에 public 키와 함께 넣게 된다. (이렇게 사인된 어셈블리를 Strong name assembly라 한다)

signing


이렇게 DLL이 사인된다면, 아래와 같이 해당 DLL의 Manifest 메타데이타 안에 public key를 갖게 된다.

strong assmebly

하지만 위의 과정에서 알 수 있듯이, 어떤 어셈블리가 사인이 되었다고 해서, 해당 어셈블리가 어셈블리에 표시된 개발자 (혹은 개발회사)에 의해 만들어 졌다는 것은 보증하지는 않는다. 즉, 누구나 AssemblyCompany 속성을 Microsoft로 지정할 수 있다. 여기서 말하는 Digital Signature는 해당 어셈블리 모듈들이 타인에 의해 변경되지 못함을 보증하는 것이지, 해당 개발자가 반드시 그들이 말하는 개발자임을 보증하는 것은 아니다. 이러한 개발자 보증은 X.509 Digital Certificate을 통해 가능한데, 이를 위해서는 VeriSign과 같은 인증기관으로부터 보증서(Certificate)를 발급받아 이것으로 다시 사인해야 한다 (Signtool.exe 사용).

어셈블리를 Sign해야 하는 이유와 사인하지 않으면 안되는 몇가지 경우는 다음과 같다.
- 어셈블리를 사인함으로써 외부 출시후 타인에 의해 어셈블리가 변경 조작되는 것을 막는다.
- 사인되지 않은 어셈블리에 대해 만약 누군가 코드 혹은 리소스를 변경했을 때, CLR 로더는 아무런 체크 없이 해당 어셈블리를 로딩할 것이다.
- 다른 중요한 제약점은 만약 어셈블리가 사인되지 않는다면, 시스템 공용으로 사용되는 GAC (Global Assembly Cache)에 해당 어셈블리를 설치할 수 없다
- 사인된 어셈블리는 사인되지 않은 어셈블리는 레퍼런스 참조로 직접 호출할 수 없다. 즉, Strong name 어셈블리가 Weak 어셈블리를 레퍼런스 참조한 후 직접 Weak 어셈블리내의 클래스를 호출할 수 없다.

관련 아티클 : 어셈블리에 Delay Sign은 왜 하는가? ( http://bit.ly/12Arfib)
 



본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.