یادداشت های یک برنامه نویس
دوستدار فرهنگ و هنر کهن ایرانی

ثبت امضای دیجیتال بر روی فایل ها (Code Signing)


پرسش امنیتی

مقدار 3 به علاوه 2 چقدر میشود؟

دیدگاه شما پس از تایید نمایش داده خواهد شد.

با استفاده از دستورات ps1 تمام فایل های exe و dll را در پوشه مورد نظر خود امضا کنید.

# Define paths and password
$certPath = "C:\Test\Certificate\CodeSignCert.pfx"
$inputPath = "C:\Test\Setup\files"
$password = "yourpfxpassword "

# Path to signtool.exe (verify this path)
$signtool = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe"

# Check if input path exists
if (-not (Test-Path $inputPath)) {
    Write-Output "Error - Input path $inputPath does not exist"
    exit
} else {
    Write-Output "Input path $inputPath found"
}

# Check if signtool.exe exists
if (-not (Test-Path $signtool)) {
    Write-Output "Error - signtool.exe not found at $signtool - Please verify the path"
    exit
} else {
    Write-Output "signtool.exe found at $signtool"
}

# Check if certificate file exists
if (-not (Test-Path $certPath)) {
    Write-Output "Error - Certificate file not found at $certPath"
    exit
} else {
    Write-Output "Certificate file found at $certPath"
}

# Get all .exe and .dll files in the input path (including subfolders)
$filesToSign = Get-ChildItem -Path $inputPath -Include *.exe,*.dll -File -Recurse -ErrorAction SilentlyContinue

# Check if any files were found
if ($filesToSign.Count -eq 0) {
    Write-Output "No .exe or .dll files found in $inputPath or its subfolders"
    Write-Output "Listing all files in $inputPath for debugging:"
    Get-ChildItem -Path $inputPath -Recurse | ForEach-Object { Write-Output " - $($_.FullName)" }
    exit
} else {
    Write-Output "Found $($filesToSign.Count) .exe or .dll files in $inputPath or its subfolders"
    $filesToSign | ForEach-Object { Write-Output " - $($_.Name) (Full path: $($_.FullName))" }
}

# Sign each file in place
foreach ($file in $filesToSign) {
    $inputFile = $file.FullName
    Write-Output "Attempting to sign $inputFile"
    # Attempt to sign the file with /fd SHA256
    $signResult = & $signtool sign /f $certPath /p $password /fd SHA256 /v /tr http://timestamp.digicert.com /td SHA256 $inputFile 2>&1
    if ($LASTEXITCODE -eq 0) {
        Write-Output "Successfully signed $inputFile"
        # Verify signature
        Write-Output "Verifying signature on $inputFile"
        & $signtool verify /pa /v $inputFile
    } else {
        Write-Output "Failed to sign $inputFile - Error: $signResult"
    }
}

در certPath مسیر فایل گواهی را بدهید (اگر ندارید و نمیخواهید خریداری کنید می‌توانید با استفاده از روشی که در پایان همین پست آمده گواهی Self-Signed ایجاد کنید.)

در inputPath مسیر فایل هایی که میخواهید امضا شوند را بدهید.

و در password پسور فایل گواهی را که در certPath قرار دادید را بدهید.

در signtool مسیر فایل signtool.exe در سیستم خود را بدهید.

سپس کد را با پسوند ps1 ذخیره کنید و PowerShell را به عنوان Administrator باز کنید و آن را اجرا کنید.

با فرض اینکه با نام SignFiles.ps1 ذخیره کرده باشید دستور اجرا به صورت زیر خواهد بود:

PowerShell -ExecutionPolicy Bypass -File C:\Test\Setup\SignFiles.ps1

 


ایجاد گواهی Self-Signed: دستورات زیر را در فایل ps1 ذخیره  و آن را اجرا کنید (yourpfxpassword و YourCompanyName را تغییر دهید):

$certPath = "C:\Test\Certificate\CodeSignCert.pfx"
$cert = New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=YourCompanyName" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
$password = ConvertTo-SecureString -String "yourpfxpassword" -Force -AsPlainText
$pfxPath = Join-Path $certPath "CodeSignCert.pfx"
Export-PfxCertificate -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" -FilePath $pfxPath -Password $password