web-dev-qa-db-ja.com

EXEでデジタル署名を確認する

私の.NETexeはsigntoolを使用して署名されています。このコードを使用して、証明書自体の有効性を確認できます。

var cert = X509Certificate.CreateFromSignedFile("application.exe");
var cert2 = new X509Certificate2(cert.Handle);
bool valid = cert2.Verify();

ただし、これは証明書自体のみをチェックし、EXEの署名はチェックしません。したがって、EXEが改ざんされた場合、このメソッドはそれを検出しません。

署名を確認するにはどうすればよいですか?

14
LTR

_wintrust.dll_から(P/Invoke)WinVerifyTrust()関数を呼び出す必要があります。 (私が知る限り)マネージド.NETには代替手段はありません。

このメソッドのドキュメントを見つけることができます ここ

誰かがすでにSOでこの質問をしました。それは受け入れられませんでしたが、正しいはずです(私はスクロールしただけです)。 見てください。

このガイド もご覧くださいが、実際には同じです。

13
pepo

Githubを検索したところ、PowerShellオブジェクトを使用して有効なAuthenticode署名を確認するAzure Microsoft C# code が見つかりました。

    /// <summary>
    /// Check for Authenticode Signature
    /// </summary>
    /// <param name="providedFilePath"></param>
    /// <returns></returns>
    private bool VerifyAuthenticodeSignature(string providedFilePath)
    {
        bool isSigned = true;
        string fileName = Path.GetFileName(providedFilePath);
        string calculatedFullPath = Path.GetFullPath(providedFilePath);

        if (File.Exists(calculatedFullPath))
        {
            Log.LogMessage(string.Format("Verifying file '{0}'", calculatedFullPath));
            using (PowerShell ps = PowerShell.Create())
            {
                ps.AddCommand("Get-AuthenticodeSignature", true);
                ps.AddParameter("FilePath", calculatedFullPath);
                var cmdLetResults = ps.Invoke();

                foreach (PSObject result in cmdLetResults)
                {
                    Signature s = (Signature)result.BaseObject;
                    isSigned = s.Status.Equals(SignatureStatus.Valid);
                    if (isSigned == false)
                    {
                        ErrorList.Add(string.Format("!!!AuthenticodeSignature status is '{0}' for file '{1}' !!!", s.Status.ToString(), calculatedFullPath));
                    }
                    else
                    {
                        Log.LogMessage(string.Format("!!!AuthenticodeSignature status is '{0}' for file '{1}' !!!", s.Status.ToString(), calculatedFullPath));
                    }
                    break;
                }
            }
        }
        else
        {
            ErrorList.Add(string.Format("File '{0}' does not exist. Unable to verify AuthenticodeSignature", calculatedFullPath));
            isSigned = false;
        }

        return isSigned;
    }
2
Veener

署名された.exeファイルの整合性を検証するために、StrongNameSignatureVerificationExメソッドを使用できます。

[DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
public static extern bool StrongNameSignatureVerificationEx(
        string wszFilePath, bool fForceVerification, ref bool pfWasVerified);    

var Assembly = Assembly.GetExecutingAssembly();
bool pfWasVerified = false;
if (!StrongNameSignatureVerificationEx(Assembly.Location, true, ref pfWasVerified))
{           
    // it's a patched .exe file!   
}

しかし、それだけでは十分ではありません。署名を削除してから、再度適用/再作成することができます。 (これを行うためのツールはたくさんあります)この場合、署名の公開鍵を(リソースとして)どこかに保存し、それを新しい/現在の公開鍵と比較する必要があります。 詳細はこちら

0
VahidN