성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 컴파일러 옵션 OSS signing / Public Signing</h1> <p> 지난 글에서 설명한 옵션과 함께,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - 재현 가능한 빌드(reproducible builds) == Deterministic builds ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/11624'>https://www.sysnet.pe.kr/2/0/11624</a> </pre> <br /> 비주얼 스튜디오 2015 업데이트 2(엄밀히 Roslyn 컴파일러)에 추가된 기능으로,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > New C# and VB features in Visual Studio 2015 Update 2 ; <a target='tab' href='https://devblogs.microsoft.com/dotnet/whats-new-for-c-and-vb-in-visual-studio/'>https://devblogs.microsoft.com/dotnet/whats-new-for-c-and-vb-in-visual-studio/</a> </pre> <br /> publicSign 옵션이 있습니다. <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Public Signing ; <a target='tab' href='https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/public-signing.md'>https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/public-signing.md</a> </pre> <br /> 말 그대로, publicKey로만 서명된 것으로,<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> <span style='color: blue; font-weight: bold'>publicSign</span>: Supports a new method of signing that is similar to delay signing except it doesn’t need to add skip verification entries to your machine. <span style='color: blue; font-weight: bold'>Binaries can be public signed with only the public key</span> and load into contexts necessary for development and testing. This is also known as OSS signing. </div><br /> <br /> 당연히 개인키 없이 서명하는 것이므로 누구에 의해 만들어졌음을 보증할 수는 없습니다. 이 옵션이 어떤 것인지는, 그것이 나오게 된 이유를 들여다보면 쉽게 알 수 있습니다.<br /> <br /> .NET Full Framework의 경우, 마이크로소프트가 만들고 배포를 했으며 이는 GAC에 등록이 됩니다. 따라서 기존의 강력한 이름 서명으로 만족할 수 있었고, 별 문제가 없었습니다. 하지만, .NET Core가 나오면서 이런 상황이 바뀝니다. .NET Core는 누구나 빌드해서 배포할 수 있는 오픈 소스 프로젝트이기 때문에 마이크로소프트가 해당 어셈블리들을 서명하기 위해 개인키를 함께 노출할 수는 없는 상황입니다. (다시 말해, 개인키 파일까지 github에 올릴 수는 없습니다.) 물론, 마이크로소프트가 배포하는 .NET Core 모듈만 개인키 서명을 하면 되고, 직접 빌드한 경우에는 서명 작업을 아예 안할 수도 있습니다. 그런데 이런 경우 문제가 발생합니다.<br /> <br /> 가령, 기존에 만들어진 프로그램이 마이크로소프트가 배포한 .NET Core를 참조했다고 가정해 보겠습니다. 즉, 프로그램에는 이미 마이크로소프트가 서명한 .NET Core를 강력한 이름의 어셈블리로 참조를 추가하고 있는 것입니다. 그런데 이 프로그램을 자신이 빌드한 .NET Core 환경에서 실행시키는 경우, 서명이 없으므로 해당 프로그램은 서명이 있는 어셈블리와 바인딩을 시도하므로 실패하게 되는 것입니다.<br /> <br /> 따라서, 자신이 빌드를 주도할 수 없는 오픈 소스 프로젝트의 경우라면 기존의 "강력한 이름 서명" 방식이 어울리지 않게 된 것입니다. 이를 위해 보완된 것이 바로 "공개 서명(Public Signing)"이고 이것이 오픈 소스 프로젝트와 어울리다 보니 한때 "<a target='tab' href='https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/oss-signing.md'>오픈 소스 서명(OSS - Open Source Signing)</a>"이라고도 불렸던 것입니다.<br /> <br /> 어찌 보면, 개인 키 서명을 미뤄두는 "delay signing"과 유사하지만 차이점이라면 별도의 서명하지 않은 어셈블리에 대한 "보안 생략 설정(Skip Verification)"을 하지 않아도 된다는 것입니다. <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 지연 서명된 DLL과 서명된 DLL의 차이점 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11258'>http://www.sysnet.pe.kr/2/0/11258</a> 지연 서명된 어셈블리를 sn.exe -Vr 등록 없이 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11259'>http://www.sysnet.pe.kr/2/0/11259</a> </pre> <br /> 이런 특징 덕분에 개발자의 환경뿐만 아니라 일반 사용자의 환경에서도 실행에 아무런 불편함이 없게 되었습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 결국, 이 기능으로 인해 마이크로소프트는 닷넷 관련 오픈 소스 프로젝트에 "공개키"만을 포함시켜도 되었고 여전히 어셈블리의 이름을 "강력한 이름(strong name)"으로 부여할 수 있게 되었습니다.<br /> <br /> 여러분들도, github에 올릴 오픈 소스가 있는데 그것에 서명하고 싶다면 (혹은, 은근히 PublicKeyToken을 자신의 개인키로 서명하던 것들과 일치시키고 싶다면) Public Signing을 이용하시면 됩니다. 방법은, 간단하게 csproj 파일에 다음의 옵션을 추가하는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <PublicSign>True</PublicSign> </pre> <br /> 하지만, 이 옵션만 주고 빌드하면 다음의 에러가 떨어집니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > error CS8102: Public signing was specified and requires a public key, but no public key was specified. </pre> <br /> 아무리 그래도 공개키는 있어야 하는 것입니다. ^^ 이를 위해 비주얼 스튜디오의 "Developer Command Prompt for VS 2017"에서 다음과 같이 sn.exe를 실행시켜 공개키를 담은 파일을 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp><span style='color: blue; font-weight: bold'>sn -k test.snk</span> Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.0 Copyright (c) Microsoft Corporation. All rights reserved. Key pair written to test.snk c:\temp><span style='color: blue; font-weight: bold'>sn -p test.snk public.snk</span> Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.0 Copyright (c) Microsoft Corporation. All rights reserved. Public key written to public.snk </pre> <br /> 위에서 보면, -k 옵션으로 개인키/공개키를 함께 담은 test.snk 파일을 생성하고 -p 옵션을 이용해 그 파일로부터 공개키만을 담은 별도의 public.snk 파일을 생성했습니다. 이제 public.snk 파일만 솔루션 폴더에 복사한 후 공개 서명할 어셈블리의 프로젝트 파일에 다음의 설정을 추가합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <SignAssembly>True</SignAssembly> <AssemblyOriginatorKeyFile>$(SolutionDir)public.snk</AssemblyOriginatorKeyFile> </pre> <br /> 빌드 후, 출력된 바이너리(dll/exe) 파일을 .NET Reflector 같은 도구를 이용해 열어 보면 다음과 같이 강력한 이름이 지정된 것을 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fd4372d50df8504c </pre> <br /> 또한, 이 파일을 참조하는 다른 어셈블리가 있다면 이에 대한 참조에 강력한 이름 형식으로 바인딩하고 있는 것을 ildasm.exe를 통해 확인할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .assembly extern ClassLibrary1 { .publickeytoken = (FD 43 72 D5 0D F8 50 4C ) // .Cr...PL .ver 1:0:0:0 } </pre> <br /> "<a target='tab' href='https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/public-signing.md'>Public Signing</a>" 글에서도 설명하고 있지만, 어셈블리에 지정된 CorFlags 값도,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [Flags] public enum CorFlags { ILOnly = 0x00000001, Requires32Bit = 0x00000002, ILLibrary = 0x00000004, StrongNameSigned = 0x00000008, NativeEntryPoint = 0x00000010, TrackDebugData = 0x00010000, Prefers32Bit = 0x00020000, } </pre> <br /> 여느 강력한 이름으로 서명된 어셈블리와 다를 바 없게 지정되어 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>[서명 전]</span> E:\ConsoleApp1\bin\Debug><span style='color: blue; font-weight: bold'>corflags ClassLibrary1.dll</span> Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.6.1055.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v4.0.30319 CLR Header: 2.5 PE : PE32 <span style='color: blue; font-weight: bold'>CorFlags : 0x1</span> ILONLY : 1 32BITREQ : 0 32BITPREF : 0 Signed : 0 <span style='color: blue; font-weight: bold'>[서명 후]</span> E:\ConsoleApp1\bin\Debug><span style='color: blue; font-weight: bold'>corflags ClassLibrary1.dll</span> Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.6.1055.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v4.0.30319 CLR Header: 2.5 PE : PE32 <span style='color: blue; font-weight: bold'>CorFlags : 0x9</span> (<span style='color: blue; font-weight: bold'> == ILOnly | StrongNameSigned</span>) ILONLY : 1 32BITREQ : 0 32BITPREF : 0 Signed : 1 </pre> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, 빌드 시에 다음과 같은 오류가 발생한다면?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Error CS8102 Public signing was specified and requires a public key, but no public key was specified. </pre> <br /> 다음의 옵션을 누락시켰기 때문입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <SignAssembly>True</SignAssembly> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
5587
(왼쪽의 숫자를 입력해야 합니다.)