我使用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} }}。
因为我只想检查程序集是否有数字证书和公司名称,不检查时间,那么有什么方法可以使用其他方式检查它是否让它为空?
答案 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
。查看数字签名属性:
请注意签名时间戳(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);