C#如何获得.dll或.exe文件数字签名者证书信息甚至证书已过期?

时间:2015-02-17 07:43:41

标签: c# .net

我使用C#检查一些exe或dll文件数字证书。

Assembly asm = Assembly.LoadFrom(assembly);


Module module = asm.GetModules().First();
System.Security.Cryptography.X509Certificates.X509Certificate certificate = module.GetSignerCertificate();
// it will null if the certificate time expired
if (null != certificate)
{
     if (certificate.Subject.Contains("Company Name"))
         Console.Write("success");
     else
         Console.Write("invalid");
}
else
{
   Console.Write("failed");
}

但现在的问题是:如果证书时间已过期,或者因为将本地时间修改为证书时间,则代码module.GetSignerCertificate()始终会获得{{1} }}。

因为我只想检查程序集是否有数字证书和公司名称,不检查时间,那么有什么方法可以使用其他方式检查它是否让它为空?

2 个答案:

答案 0 :(得分:1)

模块签名不正确。正确签名的模块在模块签名时包含时间戳。验证规则规定证书在签名时应该是有效的(在时间戳处)。请在此处阅读此答案https://stackoverflow.com/a/3428386/105929以获取更多详细信息。

如果这是您自己的模块,那么最好的操作是修改您的发布签名以在签名中包含时间戳。阅读Time Stamping Authenticode Signatures以了解 如何执行此操作(时间戳涉及证书CA提供的URL服务)。另请阅读Everything you need to know about Authenticode Code Signing

关于您的问题:如果您查看module.cs参考代码,您会发现该实施是原生的,您可以做很多事情来修改它:

    [System.Security.SecurityCritical]  // auto-generated
    [ResourceExposure(ResourceScope.None)]
    [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
    [SuppressUnmanagedCodeSecurity]
    static private extern void GetSignerCertificate(RuntimeModule module, ObjectHandleOnStack retData);

您可以使用signtool.exe验证命令,afaik它可以显示所有证书,包括缺少正确时间戳的模块上的过期证书。

  

模块是正确的。因为在它过期之前,它可以很好地使用。不要为空。它过期后,或者我改变了系统时间。它会变为空

这很容易被证明是错误的。在您的计算机上查找旧的正确签名的程序集,由一个知道正在做什么的严重供应商分发。例如。我在我的机器上发现了这个:c:\Program Files (x86)\Microsoft SQL Server\100\Setup Bootstrap\Release\x64\Microsoft.AnalysisServices.DLL。查看数字签名属性:

enter image description here

请注意签名时间戳(20110922)和证书过期(20120521)。

使用CLR API编写一个小应用程序来获取证书:

    static void Main(string[] args)
    {
        Assembly asm = Assembly.LoadFile(@"c:\Program Files (x86)\Microsoft SQL Server\100\Setup Bootstrap\Release\x64\Microsoft.AnalysisServices.DLL");
        Module m = asm.GetModules()[0];

        var cert = m.GetSignerCertificate();

        Console.WriteLine("{0}", cert);
    }

是否找到了证书?是。证书是否已过期?是。使用时间映射对模块进行正确签名吗?是。

<强> QED

答案 1 :(得分:0)

此代码在我的情况下运行良好,包括过期的证书案例。

using System.Security.Cryptography.X509Certificates;
...
// "assembly" is a string of full path for .exe or .dll.
var cert = X509Certificate.CreateFromSignedFile(assembly);