C# 어셈블리에 Delay Sign은 왜 하는 것일까?

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

이전 아티클 (http://bit.ly/14k9d86)에서 설명한 바와 같이 어셈블리의 Digital Signature를 생성하기 위해서는 private/public key pair 중 private key를 사용하게 된다. 일반적으로 개발회사에서 이 private key는 각별한 보안을 유지 하기 때문에, 개발 기간 동안은 매 빌드마다 private/public key 파일을 사용하지 않고, public key만을 가진 키 파일을 사용한다.

public key만 가진 키 파일을 사용할 경우 Digital Signature를 생성할 수 없으므로, 이를 나중에 추가할 수 있도록 자리만 빈 공간으로 남겨두고 public 키는 Manifest 에 추가한다. 이러한 사인 기법을 Delay Sign이라 부르는데, 대부분의 개발 기간동안을 Delay Sign을 사용하다가 마지막 출시 직전에 공식 사인을 하게 된다.
Delay Sign을 하는 public key 전용 키 파일은 private/public 키 파일로부터 sn.exe -p 를 이용해서 생성한다.

weak assmebly

다음으로 프로젝트 속성의 Signing 탭에서 아래와 같이 public key 전용 키 파일을 지정하고 Delay Sign only를 체크한다.

delay signing

이렇게 DLL이 Delay Sign된다면, 해당 DLL의 Manifest 메타데이타 안에 public key를 갖게 된다. 하지만, Digital Signature은 빈공간이다. 이러한 DLL을 로드할 때, CLR은 public key를 사용하여 빈 Digital Signature를 검증하려 시도할 것이므로, 이 DLL을 사용하면 아래와 같이 Strong name validation 에러가 발생하게 된다.

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'MyCSLibrary, Vers ion=1.0.0.0, Culture=neutral, PublicKeyToken=baaf24f35a6d7a99' or one of its dependencies. Strong na me validation failed. (Exception from HRESULT: 0x8013141A) ---> System.Security.SecurityException: S trong name validation failed. (Exception from HRESULT: 0x8013141A)

이러한 에러를 방지하기 위해서는 먼저 public key token을 아래와 같이 구한다. public key token은 128 byte의 public key를 다시 해싱하여 간단한 토큰으로 만든 것으로 보통 해당 DLL을 참조,사용하는 다른 DLL/EXE에서 쓰게 된다. (Manifest에 128 byte 길이의 전체 public key를 사용하는 것보다 간단한 token을 사용하여 Manifest 사이즈를 줄이고 있다)
C>sn -t publicKeyOnly.snk

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key token is baaf24f35a6d7a99

이제, 이 public key token을 아래와 같이 sn.exe -Vr 를 사용하여 개발자 머신의 레지스트리에 등록하게 된다.
C>sn -Vr *,baaf24f35a6d7a99

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Verification entry added for assembly '*,baaf24f35a6d7a99'
위의 첫 파라미터는 어셈블리명이고 * 인 경우 모든 어셈블리를 의미한다. 두번째는 public key token이고, 따라서 전체의미는 baaf24f35a6d7a99 public key를 사용하는 모든 어셈블리에 대해 CLR 로드시 어셈블리 사인 검증을 하지말라는 뜻이다.


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