2

我正在使用signtool簽署我的msi和setup.exe文件。如何查找msi是否有時間戳?

大部分msi的時間戳失敗,現在我想單獨給它們加上時間戳。

如何查找時間戳是否丟失?

以下cmdlet幫助我找到它是否簽署或不

$AuthStatus= (Get-AuthenticodeSignature $FILENAME) 

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

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

現在,我需要檢查MSI時間戳是否缺少或沒有,怎麼辦呢?

+1

你是什麼意思的「時間戳」呢?它被映射到Get-AuthenticodeSignature的哪個屬性? – 2012-01-31 14:29:09

+0

@Shay Levy:在Signtool.exe中,我們將簽名和時間戳。 [如果msi已簽名]如果我們右鍵單擊msi並查看屬性,它將具有名爲「數字簽名」的選項卡。如果您點擊數字簽名標籤,它將會有時間戳列。現在它對我來說是空的。我沒有與此匹配的確切屬性。 – Samselvaprabu 2012-01-31 14:33:48

+0

查看此[SO帖子](http://stackoverflow.com/questions/3281057/get-timestamp-from-authenticode-signed-files-in-net)一種可能的方法來確定是否有一個時間戳。 – 2012-01-31 21:11:12

回答

1

最後,我自己找到答案。有一個名爲「TimeStamperCertificate」的屬性在那裏。以下是代碼片段。

如果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 
     } 
1

以下是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 
      } 
     }  
    } 
} 
相關問題