【问题标题】:How to find whether the msi is timestamped or not?如何查找 msi 是否带有时间戳?
【发布时间】:2012-02-23 02:47:02
【问题描述】:

我正在使用 signtool 对我的 msi 和 setup.exe 文件进行签名。

大多数 msi 的时间戳都失败了,现在我想分别给它们加上时间戳。

如何查找时间戳是否丢失?

按照 cmdlet 可以帮助我找到它是否已签名

$AuthStatus= (Get-AuthenticodeSignature $FILENAME)

    If ($AuthStatus.status -ne "Valid") {

               $SIGNTOOL sign /v /f $CERPFX /t $TimestampSRVR /p $PWD $FILENAME
        }

现在我需要检查msi时间戳是否丢失,怎么办?

【问题讨论】:

  • “时间戳”是什么意思?它映射到 Get-AuthenticodeSignature 的哪个属性?
  • @Shay Levy:在 Signtool.exe 中,我们将签名和时间戳。 [如果 msi 已签名]如果我们右键单击 msi 并查看属性,它将有一个名为“数字签名”的选项卡。如果您单击数字签名选项卡,它将具有时间戳列。现在对我来说是空的。我不知道与此匹配的确切属性。
  • 查看SO post 了解确定是否存在时间戳的一种可能方法。

标签: powershell batch-file powershell-2.0 code-signing-certificate


【解决方案1】:

最后我自己找到了答案。似乎有一个名为“TimeStamperCertificate”的属性。以下是代码sn-p。

如果msi没有签名或时间戳,它会再次签名和时间戳。

$MsiAuthInfo= (Get-AuthenticodeSignature $FILENAME)

    If ($MsiAuthInfo.status -ne "Valid" -or $MsiAuthInfo.TimeStamperCertificate -eq $Null) {

               $SIGNTOOL sign /v /f $CERPFX /t $TimestampSRVR /p $PWD $FILENAME
        }

【讨论】:

    【解决方案2】:

    这是由 PowerShell MVP Vadims Podans 提供的 PowerShell 解决方案。 Get-AuthenticodeSignatureEx 在结果中添加了一个 SigningTime 属性,该值是作为通用时间(不是本地时间)的日期时间,您始终可以在 datetime 对象上调用 ToLocalTime() 以获取您所在时区的结果。可以使用如下命令快速测试:

    dir $pshome\*.ps1xml | Get-AuthenticodeSignatureEx | ft SignerCertificate,Status,SigningTime,Path
    
    
    function Get-AuthenticodeSignatureEx
    {
        [CmdletBinding()]
    
        param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [String[]]$FilePath
        )
    
        begin
        {
            $signature = @"
            [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool CryptQueryObject(
                int dwObjectType,
                [MarshalAs(UnmanagedType.LPWStr)]string pvObject,
                int dwExpectedContentTypeFlags,
                int dwExpectedFormatTypeFlags,
                int dwFlags,
                ref int pdwMsgAndCertEncodingType,
                ref int pdwContentType,
                ref int pdwFormatType,
                ref IntPtr phCertStore,
                ref IntPtr phMsg,
                ref IntPtr ppvContext
            );
            [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool CryptMsgGetParam(
                IntPtr hCryptMsg,
                int dwParamType,
                int dwIndex,
                byte[] pvData,
                ref int pcbData
            );
            [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool CryptMsgClose(
                IntPtr hCryptMsg
            );
            [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool CertCloseStore(
                IntPtr hCertStore,
                int dwFlags
            );
    "@
            Add-Type -AssemblyName System.Security
            Add-Type -MemberDefinition $signature -Namespace PKI -Name Crypt32
        }
    
        process
        {
            Get-AuthenticodeSignature @PSBoundParameters | ForEach-Object {
                $Output = $_
                if ($Output.SignerCertificate -ne $null) {
                    $pdwMsgAndCertEncodingType =  0
                    $pdwContentType =  0
                    $pdwFormatType =  0
                    [IntPtr]$phCertStore = [IntPtr]::Zero
                    [IntPtr]$phMsg = [IntPtr]::Zero
                    [IntPtr]$ppvContext = [IntPtr]::Zero
                    $return = [PKI.Crypt32]::CryptQueryObject(
                        1,
                        $_.Path,
                        16382,
                        14,
                        $null,
                        [ref]$pdwMsgAndCertEncodingType,
                        [ref]$pdwContentType,
                        [ref]$pdwFormatType,
                        [ref]$phCertStore,
                        [ref]$phMsg,
                        [ref]$ppvContext
                    )
    
                    $pcbData = 0
                    $return = [PKI.Crypt32]::CryptMsgGetParam($phMsg,29,0,$null,[ref]$pcbData)
                    $pvData = New-Object byte[] -ArgumentList $pcbData
                    $return = [PKI.Crypt32]::CryptMsgGetParam($phMsg,29,0,$pvData,[ref]$pcbData)
                    $SignedCms = New-Object Security.Cryptography.Pkcs.SignedCms
                    $SignedCms.Decode($pvData)
                    foreach ($Infos in $SignedCms.SignerInfos) {
                        foreach ($CounterSignerInfos in $Infos.CounterSignerInfos) {
                            $sTime = ($CounterSignerInfos.SignedAttributes | Where-Object {$_.Oid.Value -eq "1.2.840.113549.1.9.5"}).Values | Where-Object {$_.SigningTime -ne $null}
                        }
                    }
                    $Output | Add-Member -MemberType NoteProperty -Name SigningTime -Value $sTime.SigningTime -PassThru -Force
                    [void][PKI.Crypt32]::CryptMsgClose($phMsg)
                    [void][PKI.Crypt32]::CertCloseStore($phCertStore,0)
                } else {
                    $Output
                }
            }    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-03
      • 2015-05-31
      相关资源
      最近更新 更多