2013-04-11 2 views
10

서명 된 인증서를 확인하지 않고 파일에 디지털 서명이 있는지 확인하는 간단한 방법은 있습니까?실제로 서명을 확인하지 않고 파일에 디지털 서명이 있는지 확인합니다.

디렉토리에 exe & dll 파일의 긴 목록을 서명하고 싶지만 아직 서명되지 않은 파일 만 서명하고 싶습니다.

예를 들어 파일 중 하나에 Microsoft 또는 다른 제 3자가 서명 한 경우 회사 인증서로 다시 서명하지 않으려 고합니다.

파일을 마우스 오른쪽 버튼으로 클릭하고 속성 (디지털 서명 탭이 나타나면 서명 된 경우)을 보면 파일에 디지털 서명이 있는지 여부를 쉽게 확인할 수 있습니다. C#을 사용하여이 디지털 서명 속성을 확인하는 간단한 방법을 찾고 있습니다.

지금은 signtool.exe와 함께 verify 명령을 사용하고 있습니다. 디지털 서명이 있는지를 확인할뿐만 아니라 파일에 서명하는 데 사용 된 인증서가 신뢰할 수있는 기관에서 발급되었는지 여부도 확인합니다. 나는 자세한 플래그 "/ V"를 사용하고 출력 텍스트가 포함 된 경우 확인하고 있습니다

private static Boolean alreadySigned(string file) 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo(); 
      startInfo.RedirectStandardOutput = true; 
      startInfo.RedirectStandardError = true; 
      startInfo.FileName = "signTool.exe"; 
      startInfo.Arguments = "verify /v " + file; 
      startInfo.UseShellExecute = false; 

      Process process = new Process(); 
      process.StartInfo = startInfo; 
      process.EnableRaisingEvents = true; 
      process.Start(); 
      process.WaitForExit(); 
      string output = process.StandardOutput.ReadToEnd(); 

      return output.Contains("Signing Certificate Chain:"); 
     } 

공지 사항 : 여기

이 일을 내 간단하면서도 투박한 접근 방식이다 "서명 인증서 체인을" - 그 문자열은 항상 서명 된 파일의 출력에 있음을 알았 기 때문에 - 서명되지 않은 파일에서는 생략되었습니다.

어쨌든, 어색하지만이 코드는 작업을 완료 한 것으로 보입니다. 한 가지 이유는 파일을 확인하는 명령을 실행하는 데 수백 밀리 초가 걸리기 때문입니다. 파일에 디지털 서명이 있는지 확인하려고하는 인증서를 확인할 필요가 없습니다.

간단히 말해 디지털 서명이 있는지 확인하지 않고도 확인할 수있는 간단한 방법이 있습니까?

+0

p.s. 수백 밀리 초를 걱정하는 것은 까다 롭다 고 생각할 수도 있지만, 수천 개의 파일을 검사하는 경우 추가됩니다. – ksun

+0

느린 이유는 서명을 확인하기 때문이 아니라 모든 파일에 대해 새 프로세스를 생성하기 때문에 속도가 느린 이유입니다. Bouncy Castle과 같이 C# 고유의 디지털 서명 라이브러리를 가져옵니다. –

답변

9

"Get-AuthenticodeSignature"powershell 명령을 사용하여 꽤 괜찮은 해결책을 찾았습니다. C#에서 powershell 명령을 사용하는 방법을 설명하는 this site을 발견했습니다. 이렇게하면 여러 프로세스를 생성 할 필요가 없으며 꽤 빠릅니다.

using System.Collections.ObjectModel; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 


private static Boolean alreadySigned(string file) 
{    
      try 
      { 
       RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); 
       Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); 
       runspace.Open(); 

       Pipeline pipeline = runspace.CreatePipeline(); 
       pipeline.Commands.AddScript("Get-AuthenticodeSignature \"" + file + "\""); 

       Collection<PSObject> results = pipeline.Invoke(); 
       runspace.Close(); 
       Signature signature = results[0].BaseObject as Signature; 
       return signature == null ? false : (signature.Status != SignatureStatus.NotSigned); 
      } 
      catch (Exception e) 
      { 
       throw new Exception("Error when trying to check if file is signed:" + file + " --> " + e.Message); 
      } 
} 
+1

System.Management.Automation 참조를 프로젝트에 추가했는지 확인하십시오. 이 파일은 다음 위치에 있어야합니다. C : \ Program Files \ Reference Assemblies \ Microsoft \ WindowsPowerShell \ v1.0 – ksun

+1

NuGet의 PowerShell 3.0 API에서도 제대로 작동합니다. –

1

우선 signtool은 PE 파일에서만 작동합니다. 다른 파일 형식의 경우 서명을 바꿈하거나 포함 된 서명 또는 분리 된 서명을 사용하여 서명 할 수 있습니다.

감싸는 서명은 실제 파일을 변경하여 일반적으로 읽는 데 사용되는 응용 프로그램에서 읽지 못하게합니다. 예 : PDF에 줄 바꿈 서명을 만들면 서명이 제거 될 때까지 PDF 도구가 파일을 읽을 수 없습니다.

일부 파일 형식은 포함 된 서명을 해당 형식으로 지원합니다 (EXE 파일 및 Authenticode 형식이 그 예입니다). 여기서 서명을 파일에 포함시킬 수 있으며 다른 응용 프로그램에서도 서명을 읽을 수 있습니다. 그러나 이것은 형식에 따라 다르며 많은 형식이이를 지원하지는 않습니다.

마지막으로 분리 된 서명은 파일과 별도로 보관됩니다. 나는. 파일이 a.txt 인 경우 분리 된 서명을 작성한 후이를 넣으십시오 (예 : a.txt.pkcs7detached).

위에서 알 수 있듯이 분리 된 서명은 작업에 가장 적합합니다. 이 경우 .pkcs7detached 파일 목록을 확인하여 파일에 서명이있는 .pkcs7detached 파일이없는 경우 새 서명을 만듭니다.

위의 모든 서명 유형은 SecureBlackbox 제품의 PKIBlackbox 패키지에서 지원됩니다.당신이 .NET 어셈블리에 대해이 작업을 수행하려면

+0

유진 감사합니다. 나는 내 질문에 내가 실제로 DLL 및 실행 파일 (내 질문에 잘못 명시된 모든 파일이 아닌) 서명에만 관심이 있다고 언급하는 것을 게을리했다. 이것은 우리가 dll이나 실행 파일이 아닌 파일에 서명하기로 결정한 경우에 알 수있는 좋은 정보입니다. – ksun

+0

@ksun이 경우 Authenticode 구성 요소를 사용할 수 있습니다.이 구성 요소를 사용하면 Authenticode가 서명의 유효성을 검사하지 않고 파일에 있는지 확인할 수 있습니다. 또한 PE 파일의 Authenticode와 관리되는 어셈블리의 강력한 이름 지정은 관리되는 어셈블리에서 함께 사용할 수있는 여러 가지 사항입니다. –

+0

팁 주셔서 감사. [Authenticode on MSDN] (http://msdn.microsoft.com/en-us/library/ms537364(v=vs.85).aspx) ChkTrust 명령이 작동하는 것 같습니다. 나는 이것도 인증서의 유효성을 확인 믿습니다. 그러나 나는 [다른 게시물]을 발견했습니다. (http://stackoverflow.com/questions/5555214/what-is-the-best-way-to-check-programatically-if-dll-exe-file-is-signed- with-aut)를 StackOverflow에 설치하면 powershell 명령으로 authenticode 서명을 쉽게 확인할 수 있습니다. Get-AuthenticodeSignature 우리는 현재 파일의 이름을 강력하게 지정하지 않습니다. – ksun

4

, 당신은이 작업을 수행 할 수 있습니다

 string filePath = "C:/path/to/file.dll"; 
     Assembly assembly = Assembly.LoadFrom(filePath); 
     Module module = assembly.GetModules().First(); 
     X509Certificate certificate = module.GetSignerCertificate(); 
     if (certificate == null) 
     { 
      // file is not signed. 
     } 

X509Certificate 클래스는 사용 (예 : CreateFromSignedFile)이 될 수있는 몇 가지 정적 메소드를 가지고 있지만, 나뿐만 아닙니다 그들에게 익숙하다. 이것은 내부 도구로 디지털 서명을 적용했는지 다시 확인하는 데 사용하는 방법입니다.

+0

이것은 훌륭한 솔루션 인 것처럼 보이지만 C++에서 컴파일 된 .NET 어셈블리와 관리되지 않는 어셈블리를 혼합하여 사용합니다. 내가 잘못했다면 나를 바로 잡으십시오. 그러나이 솔루션은 C++에서 컴파일 된 관리되지 않는 어셈블리에서 작동하지 않을 것이라고 생각합니다. – ksun

+0

이것은 내 앱 (모든 관리 코드 C# DLL)에 필요한 솔루션입니다. 그러나 하나 이상의 인증서를 포함 할 수있는 곳에서도 파일에 "추가"할 수 있습니다. 위의 코드는 인증서가 하나만있는 경우에만 처리됩니다. –

관련 문제