본문 바로가기

IT 살이/04. 기술 - 프로그래밍

강력한 / 약한 이름의 어셈블리(일치 비교, 배포, 보안체크)

1. 어셈블리의 일치 비교(assembly identity comparison)

어셈블리의 일치 비교는 어셈블리가 바인딩이 되고 로딩이 일어나려 할때 수행되고, 또한 어셈블리가 로딩되면, 로딩된 어셈블리의 캐시( LoadContext, LoadFromContext)에 캐싱이 되는데 새로운 어셈블리를 로딩하려고 할때 이 어셈블리가 이미 로딩되어 캐시에 있는지를 확인할때도 어셈블리 일치에 대한 비교 작업이 수행된다. 이런 어셈블리 일치에 대한 판정은 강력한 이름의 어셈블리과 약한 이름의 어셈블리가 다른 비교 로직을 거치게 된다.

강력한 이름의 어셈블리와 약한 이름의 어셈블리는 내부 구조에 있어서는 동일하다. 구조적인 면에서의 차이점은 강력한 이름의 어셈블리는 디지털 사인을 추가했다는 것이다. 디지털 사인이 추가된다는 것은 어셈블리에 고유한 이름이 추가되고 동일한 이름(fully qualified assembly name)의 다른 어셈블리가 없다고 보장할 수 있다는 것이다.

어셈블리 바인딩에 대한 예를 들어본다. 이제 어셈블리 파일에 대한 위치를 확인한 후라고 하자. CLR은 호출하는 어셈블리가 가지고 있는 메너페스트의 참조 정보를 통해서 대상 어셈블리가 강력한 이름의 어셈블리라고 판단되면, 단순히 어셈블리 파일명으로만 원하는 어셈블리라고 결정하는 것은 아니다. 즉 목표로 하는 어셈블리명과 동일한 이름을 갖는 파일을 찾기는 했지만 그것이

원하는 어셈블리인지 확인하는 방법은 어셈블리의 완전한 이름(fully qualified name)의 비교

를 통해서이다. 예를 들어 어셈블리 파일명이 component.dll이고, 이것의 완전한 이름이 다음과 같다고 해보자.

“component, version=1.2.3.4, culture=neutral, publickeytoken=123456789012”

강력한 이름의 어셈블리는 공용 저장소 GAC에 다른 버전의 어셈블리가 동시에 등록될 수 있다. 공용저장소 GAC의 구조를 알고 나면 이해가 갈 것이다. GAC은 공용저장소로도 사용되지만 버전 정책이 실행될 수 있는 구조를 가지고 있다. 그래서 GAC에는 다음과 같은 어셈블리가 앞의 버전의 어셈블리와 동시에 저장되어 있을 수 있다.

“component, version=1.2.3.5, culture=neutral, publickeytoken=123456789012”

이 둘중의 어떤 어셈블리를 선택할지는 호출하는 어셈블리가 가지고 있는 어셈블리의 완전한 정보를 서버 비교해서 결정을 내리게 된다. 만약 버전 정책을 가지고 있는 config 파일이 있다면 그 내용을 적용한 후 결정되는 어셈블리의 완전한 이름과 대상 어셈블리의 완전한 이름이 비교될 것이다.

약한 이름의 어셈블리인 경우는 어셈블리 정보중에서 호출하는 어셈블리와 대상 어셈블리의 어셈블리 이름만 같은면 된다. 어셈블리 일치 비교에 버전과 컬쳐 정보는 포함되지 않는다. 그러나 공개키 비교는 포함된다.
예를 들어 빌드할때는 대상 어셈블리에 공개키가 없는 약한 이름이었다고 하자. 근데 대상 어셈블리를 다시 강력한 이름으로 만들어서 약한 이름의 어셈블리가 있는 곳에 강력한 이름의 버전의 파일로 덮어쓰기를 했다고 하자. 호출하는 어셈블리는 정상적으로 파일을 찾아서 로딩시킬수 있을까? 파일 검색은 할 수 있지만 어셈블리 로딩에서 에러가 발생한다. fuslogvw.exe 툴은 공개키가 맞지 않는다는 로그를 남긴다.

2. 어셈블리별 배포

약한 이름의 어셈블리는 공용 저장소 GAC에 등록될 수 없으므로 결국 애플리케이션마다 복사되어 배포되어야 한다.  그러나 강력한 이름의 어셈블리는 GAC에 등록되어 여러 애플리케이션에서 공유할 수 있도록 배포될 수 있으면서 그리고 동시에 애플리케이션 전용으로 애플리케이션 디렉토리에 복사될 수도 있다.

약한 이름의 어셈블리
- 전용 배포 가능
- 공용 배포 불가
강력한 이름의 어셈블리
- 전용 배포 가능
- 공용 배포 가능

3. 보안 체크

약한 이름의 어셈블리와 강력한 이름의 어셈블리는 어셈블리의 로딩시 보안 체크 과정을 거치느냐에도 차이가 있다. 약한 이름의 어셈블리는 공개키, 디지털 사인이 없다. 이런 경우는 호출하는 어셈블리와 대상 어셈블리의 로딩시 코드 변경 체크가 수행되지 않는다. 그러나 강력한 이름의 어셈블리는 코드 변경 체크를 거치게 된다. 다만 GAC으로 배포되는 경우는 GAC에 등록될 때만 코드 변경 여부를 체크하고 GAC이외의 디렉토리로 전용 배포된 경우는 로딩될때마다 체크를 하게 된다.