ファイルがデジタル署名されているかどうかをプログラムで確認したいと思います。
今のところ、私はかなりあいまいなものを見つけました MSDNのコード 、それはコンパイルしません...
このテーマに関するアイデアはありますか?
ちなみに、コマンドラインを備えた外部ツールも素晴らしいでしょう。
Signtoolに言及する回答の重要な欠落部分は次のとおりです。
はい。ファイルが署名されているかどうかは、よく知られているsigntool.exeでも確認できます。別のツールをダウンロードする必要はありません!
例えば。簡単な行で:
signtool verify /pa myfile.exe
if %ERRORLEVEL% GEQ 1 echo This file is not signed.
(冗長出力の場合は、「/ pa」の後に「/ v」を追加します。)
なぜこれが重要なのでしょうか?ファイルに署名するだけで(再度)署名されることになり、機能します。
私の目的は、ビルドをクリーンに保ち、日付が変更されるだけでなく、その後バイナリが異なるため、ファイルに2回署名しないことです。
ビジネスの例:私のクライアントには、合理化された自動化された「dev ops」の種類のビルドおよびポストビルドプロセスがあります。さまざまなファイルセットには複数のソースがあり、最後にビルド、テスト、および配布へのバンドルが行われます。そのためには、いくつかのファイルに署名する必要があります。一部のファイルが署名されずにユニットを離れないことを保証するために、すでに署名されている場合でも、すべての重要なファイルに署名していました。
しかし、これは十分にきれいではありません:
1)既に署名されているファイルに再度署名すると、ファイルの日付とバイナリフィンガープリントが変更され、単純にコピーされた場合、ファイルはソースとの比較可能性を失います。 (少なくとも、タイムスタンプを使用して署名する場合、これは常に実行されるため、強くお勧めします。)
このファイルは、他のファイルソースの前のファイルと比較できなくなっているため、これは深刻な品質の低下です。
2)ファイルに再度署名する場合、これも障害である可能性があり、それはサードパーティのファイルであり、ユニットによって署名されるべきではありません。
前述の「signtool verify」呼び出しの戻りコードに応じて署名自体を条件付きにすることで、両方を回避できます。
ダウンロード Sigcheck y次のコマンドを使用します。
sigcheck.exe -a -u -e
署名済みdllの例
署名されていないdllの例
Sigcheckは、ファイルバージョン番号を表示するコマンドラインユーティリティです。幸運を
外部ツールが必要な場合は、signtool.exeを使用できます。これはWindows SDKの一部であり、コマンドライン引数を取ります。詳細については、こちらをご覧ください http://msdn.Microsoft.com/en-us/library/aa387764.aspx
Webで別のオプション(純粋な.Netコード)を見つけました here 。
コードは非常にシンプルで動作します。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string filePath = args[0];
if (!File.Exists(filePath))
{
Console.WriteLine("File not found");
return;
}
X509Certificate2 theCertificate;
try
{
X509Certificate theSigner = X509Certificate.CreateFromSignedFile(filePath);
theCertificate = new X509Certificate2(theSigner);
}
catch (Exception ex)
{
Console.WriteLine("No digital signature found: " + ex.Message);
return;
}
bool chainIsValid = false;
/*
*
* This section will check that the certificate is from a trusted authority IE
* not self-signed.
*
*/
var theCertificateChain = new X509Chain();
theCertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
/*
*
* Using .Online here means that the validation WILL CALL OUT TO THE INTERNET
* to check the revocation status of the certificate. Change to .Offline if you
* don't want that to happen.
*/
theCertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
theCertificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
theCertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chainIsValid = theCertificateChain.Build(theCertificate);
if (chainIsValid)
{
Console.WriteLine("Publisher Information : " + theCertificate.SubjectName.Name);
Console.WriteLine("Valid From: " + theCertificate.GetEffectiveDateString());
Console.WriteLine("Valid To: " + theCertificate.GetExpirationDateString());
Console.WriteLine("Issued By: " + theCertificate.Issuer);
}
else
{
Console.WriteLine("Chain Not Valid (certificate is self-signed)");
}
}
}
}
また、npmパッケージsign-check
そのため。
このパッケージはWinVerifyTrust APIを実装し、簡単な使用法があります。
npm install -g sign-check
sign-check 'path/to/file'