如果证书本身未安装在工作站上而仅用于签署该特定文件,是否可以通过某种方式以编程方式导出文件的数字证书主题?
我需要以某种方式从文件中提取该信息并检查其是否正确。最好使用 Python/CMD/PowerShell
编辑:
抱歉,缺乏详细信息。
我目前正在使用这个python脚本(我修改了它以便在Python 3.6上运行):http://www.zedwood.com/article/python-openssl-x509-parse-certificate使用我找到的这个小工具来解析从原始可执行文件中提取的 .cer 文件(我也对其进行了修改以适用于 Python 3):https://blog.didierstevens.com/programs/disitool/但只有在我使用 Windows certutil 将其从 DER 编码的二进制文件转换为 base-64 之后才可以。
但是,disitool 脚本的问题在于,它实际上使用 pefile python 模块从可执行文件本身剪切出一个“签名”字节数组,这导致提取的 .cer 文件无效,正如我在尝试使用 OpenSSL.crypto 模块加载证书时不断收到的 python 错误一样:
[('asn1 encoding routines', 'asn1_check_tlen', 'wrong tag'), ('asn1 encoding routines', 'asn1_item_embed_d2i', 'nested asn1 error'), ('asn1 encoding routines', 'asn1_template_noexp_d2i', 'nested asn1 error'), ('PEM routines', 'PEM_ASN1_read_bio', 'ASN1 lib')]
但是解析一个好的提取证书(使用我上面发布的第一个脚本)是有效的,正如您在此处看到的:
所以,我猜我只需要一种从可执行文件中提取证书的方法。或者,如果您发现我的解决方案太复杂,如果您知道我如何从证书的主题字段中获取“Redmond”文本,我非常乐意听取您的想法 :)
答案1
在 Powershell 中:
Get-AuthenticodeSignature C:\Path\TO\File.exe
因此,使用 explorer.exe 的示例,这将获得 Redmond:
(Get-AuthenticodeSignature C:\Windows\explorer.exe).SignerCertificate.subject.split(',')[2].split('=')[1]
由于您要求详细说明,因此Get-AuthenticodeSignature
返回一个 System.Management.Automation.Signature 对象。您可以通过几种方式找到它。就我个人而言,我更喜欢将其分配给一个变量,这样我就可以进一步处理返回的对象。一旦将其分配给变量,您就可以了解有关它的信息。Get-Member
应该是您在 Powershell 中使用的 cmdlet 之一。在这种情况下:
$foo = Get-AuthenticodeSignature C:\Windows\explorer.exe
Get-Member -InputObject $foo
TypeName: System.Management.Automation.Signature
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
IsOSBinary Property bool IsOSBinary {get;}
Path Property string Path {get;}
SignatureType Property System.Management.Automation.SignatureType SignatureType {get;}
SignerCertificate Property System.Security.Cryptography.X509Certificates.X509Certificate2 SignerCertificate {...
Status Property System.Management.Automation.SignatureStatus Status {get;}
StatusMessage Property string StatusMessage {get;}
TimeStamperCertificate Property System.Security.Cryptography.X509Certificates.X509Certificate2 TimeStamperCertific...
因此,您可以看到该对象具有一些方法和一些属性(我知道,所有对象都有)。在这种情况下,方法都是从 System.Object 继承的标准方法。但是属性很有趣。SignerCertificate 看起来像您想要的那样,所以让我们看看它是什么样子:
$foo.SignerCertificate
Thumbprint Subject
---------- -------
419E77AED546A1A6CF4DC23C1F977542FE289CF7 CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
指纹显然很重要,因为它可以识别证书,但您询问的是主题中的 Redmond。所以现在我们知道如何将其作为字符串获取:
$foo.SignerCertificate.Subject
因此从这里开始只是直接字符串解析。
由于您似乎正在学习 Powershell,因此我还要补充一点。您应该经常尝试的另一个 cmdlet 是 Get-Command。在这种情况下,在您提出问题之前,我甚至不知道 Get-AuthenticodeSignature cmdlet 存在。所以我这样做了:
Get-Command *signature*
CommandType Name Version Source
----------- ---- ------- ------
Function Update-MpSignature 1.0 Defender
Cmdlet Get-AuthenticodeSignature 3.0.0.0 Microsoft.PowerShell.Security
Cmdlet Save-VolumeSignatureCatalog 1.0.0.0 ShieldedVMDataFile
Cmdlet Set-AuthenticodeSignature 3.0.0.0 Microsoft.PowerShell.Security
答案2
在 powershell 中:你可以在 CN 中使用逗号,然后 whis 对我有用:
(Get-AuthenticodeSignature C:\Windows\explorer.exe).SignerCertificate.subject.split('=')[1].split('"=')[1]