[c#] 공개 키 토큰의 역할은 무엇입니까?

공개 키 토큰의 역할은 무엇입니까? 서명 된 해시를 해독하는 데 어떤 부분이 있습니까? GAC에서 동일한 공개 키 토큰을 사용하는 Microsoft의 어셈블리가 많은 이유는 무엇입니까?



답변

공개 키 토큰의 역할은 무엇입니까?

공개 키 토큰은 공개 키를 나타내는 편리한 “토큰”인 작은 숫자입니다. 공개 키는 매우 깁니다. 공개 키 토큰의 목적은 전체 키를 말하지 않고 키를 참조 할 수 있도록하는 것입니다. “반지의 제왕”이라고 말하는 것과 같은 방식으로 5 백만 단어의 소설 을 대표 하는 다섯 단어입니다 . 그것에 대해 이야기하고 싶을 때마다 그 50 만 단어를 말해야한다면 다소 불편할 것입니다.

서명 된 해시를 해독하는 데 어떤 부분이 있습니까?

아니요. 공개 키 토큰에는 “정보”가 없습니다. 공개 키 를 나타내는 숫자 일뿐 입니다. 그 자체가 공개 키가 아닙니다.

동일한 공개 키 토큰을 사용하는 Microsoft의 어셈블리가 너무 많은 이유는 무엇입니까?

모두 동일한 개인 키 (Microsoft의 개인 키)로 서명되었으므로 모두 동일한 공개 키로 확인되므로 모두 동일한 공개 키 토큰을 갖습니다.


답변

에서 위키 백과

“공개 키 토큰은 어셈블리 이름을 고유하게 만드는 데 사용됩니다. 따라서 두 개의 강력한 이름의 어셈블리는 동일한 PE 파일 이름을 가질 수 있지만 .NET은이를 다른 어셈블리로 인식합니다. Windows 파일 시스템 (FAT32 및 NTFS)은 PE 파일 이름이므로 동일한 PE 파일 이름 (그러나 다른 문화권, 버전 또는 공개 키 토큰)을 가진 두 개의 어셈블리가 동일한 Windows 폴더에 존재할 수 없습니다.이 문제를 해결하기 위해 .NET은 GAC (Global Assembly Cache)라는 것을 도입했습니다. .NET CLR에서 단일 폴더로 처리되지만 실제로는 중첩 된 NTFS (또는 FAT32) 폴더를 사용하여 구현됩니다.

크래커가 다른 것으로 보이는 어셈블리를 속이려는 스푸핑 공격을 방지하기 위해 어셈블리는 개인 키로 서명됩니다. 의도 된 어셈블리의 개발자는 개인 키를 비밀로 유지하므로 크래커가 액세스 할 수 없으며 추측 할 수도 없습니다. 따라서 크래커는 자신의 어셈블리를 다른 것으로 가장 할 수 없으며 변경 후 올바르게 서명 할 가능성이 없습니다. 어셈블리 서명에는 어셈블리의 중요한 부분에 대한 해시를 가져온 다음 개인 키로 해시를 암호화하는 작업이 포함됩니다. 서명 된 해시는 공개 키와 함께 어셈블리에 저장됩니다. 공개 키는 서명 된 해시를 해독합니다.CLR이 강력한 이름의 어셈블리를로드하면 어셈블리에서 해시를 생성 한 다음이를 해독 된 해시와 비교합니다. 비교가 성공하면 파일의 공개 키 (및 따라서 공개 키 토큰)가 어셈블리에 서명하는 데 사용되는 개인 키와 연결되어 있음을 의미합니다. 이는 어셈블리의 공개 키가 어셈블리 게시자의 공개 키이므로 스푸핑 공격이 차단됨을 의미합니다. “


답변

해시는 일종의 “지문”입니다. 서명자가 소유 한 (유일하게 알려진) 개인 키를 사용하여 서명됩니다. 서명자의 공개 키를 알고있는 경우 해시가 실제로 서명자로부터 온 것인지, 따라서 데이터 / 파일이 실제로 서명자로부터 온 것인지 (변경되지 않았는지) 확인할 수 있습니다. GAC의 일부 파일에 대한 동일한 공개 키는 “모두 동일한 서명자가 서명 함”을 의미합니다.


답변

공개 키 토큰은 실제 공개 키에서 다소 읽을 수있는 발췌 부분입니다. 완전한 공개 키는 서명 된 어셈블리 내에 저장되며 서명을 해독하는 데 사용됩니다 (= 암호화 된 해시). 로더는이를 사용하여 내용물이 변조 (또는 손상)되지 않았는지 확인합니다. 원래 해시는 개인 키를 사용하여 작성자가 암호화했으며 해당 키를 소유 한 사람 만 유효한 서명을 생성 할 수 있습니다.

각 회사 (또는 부서)는 하나의 키 쌍만 사용해야하므로 GAC에 동일한 PKT 그룹이 표시됩니다.


답변

이전 답변 (특히 Wikipedia의 인용문이있는 답변)에 공개 / 개인 키를 통한 강력한 이름 지정이 변경된 어셈블리를 얻거나 누군가가 어셈블리를 조작하는 것을 방지하지 못한다는 점을 추가하고 싶습니다.

우선 , 강력한 이름은 어셈블리를 신뢰할 수 있음을 보장하지 않습니다. 공개 키 / 공개 키 토큰이 있지만 서명 한 사람을 알지 못합니다 (어떻게 든 어셈블리 공개 키를 소유하고 있음을 알리는 경우 제외).

예를 들어 해커는 어셈블리를 가져 와서 강력한 이름을 제거하고 (이를 수행하는 도구가 있음) 고유 한 강력한 이름으로 서명 할 수 있습니다. 신뢰를 위해 인증서로 서명하는 다른 종류의 디지털 코드가 있습니다. 제 3자가 귀하와 귀하의 회사를 확인하는 것이 포함되며 무료가 아닙니다. Authenticode 기술을 확인하십시오.

https://msdn.microsoft.com/en-us/library/ms537359(v=vs.85).aspx

둘째 , 다음 토론에서는 변조 된 어셈블리에 대해 동일한 해시를 생성하는 동일한 공개 키 토큰으로 공개 / 개인 키 쌍을 가져 오는 무차별 대입 공격 방법에 대해 간략하게 설명했습니다.

https://groups.google.com/forum/?hl=ko#!topic/microsoft.public.dotnet.security/Jo6PqypxJN8

이 문제는 향상된 강력한 이름 지정 https://docs.microsoft.com/en-us/dotnet/framework/app-domains/enhanced-strong-naming에 의해 해결되었을 수 있습니다.

또한 어셈블리 유효성 검사를 건너 뛰고 변경된 어셈블리를 런타임에로드 할 수있는 버그가 토론에서 언급되었습니다. 자세한 연구는 여기에 있습니다. 버그는 이후 버전의 .Net 프레임 워크에서 수정되었습니다 (따라서 이전 .Net 1에 존재하는 버그).

http://www.grimes.nildram.co.uk/workshops/fusionWSCrackThree.htm

셋째 , 어셈블리로드 성능을 높이기 위해 .Net 3.5 sp1을 시작하는 것은 완전 신뢰 어셈블리에 대해 기본적으로 유효성이 검사되지 않습니다.

https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature

어셈블리 조건 :
https://blogs.msdn.microsoft.com/shawnfa/2008/05/14/strong-name-bypass/

Stack Overflow에 대한 토론 :
서명 된 .net 어셈블리가로드 될 때 완전히 확인되어 수정되지 않았는지 확인합니까?

내가 이해했듯이 이것은 어셈블리가로드 중에 해싱되지 않았는지 확인하기 위해

마지막으로 어셈블리 버전을 지정해야하기 때문에 강력한 이름 지정의 장단점에 대한 논쟁이 있음을 언급하고 싶습니다. Microsoft는 일부 제품에서 강력한 이름을 제거합니다.
https://www.pedrolamas.com/2016/03/01/still-strong-naming-your-assemblies-you-do-know-its-2016-right/

결론적으로, 언급 된 모든 사항을 요약하고 싶었습니다. 강력한 이름 지정을 접했을 때 MSDN 및 Wikipedia에서 어셈블리에 대한 일종의 방어를 제공 할 수 있다는 오해를 받았습니다. 나는 “Cool”과 강력한 이름이 보호 메커니즘으로 내 기억에 남아 있다고 생각했다. 개인 키를 사용하여 snk 파일의 안전성에 대해 생각해야 할 때까지 동료가 “멋지다”는 것이 아니라고 말했습니다. 그래서 저는 약간의 조사를했습니다. 가장 먼저 배운 것은 강력한 이름이 신뢰를 의미하는 것이 아니라 인증서를 사용해야한다는 것입니다. 그래도 개인 키를 안전하게 보관하면 변조 된 어셈블리에 서명하지 않을 것이라고 생각했습니다. 즉, 누군가가 내 어셈블리를 수정하면 서명도 수정해야하고 수정 된 어셈블리는로드되지 않습니다. CLR. 이제 나는 강력한 이름 지정이이를 보장한다고 생각합니다. 따라서 어셈블리의 고유성을 보장하는 데에만 의존해야합니다.

추신. 참조가 많은 긴 게시물에 대해 죄송합니다.


답변