我正在使用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时间戳是否丢失,怎么做?
答案 0 :(得分: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 :(得分:1)
这是一个PowerShell解决方案,由PowerShell MVP Vadims Podans提供。 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
}
}
}
}