Вот тот же метод, предоставленный @ Sir Kill A Lot в его ответе , но преобразованный в скрипт PowerShell ( pfx2snk.ps1 ).
Param(
[Parameter(Mandatory=$True,Position=1)]
[string] $pfxFilePath,
[string] $pfxPassword
)
# The path to the snk file we're creating
[string] $snkFilePath = [IO.Path]::GetFileNameWithoutExtension($pfxFilePath) + ".snk";
# Read in the bytes of the pfx file
[byte[]] $pfxBytes = Get-Content $pfxFilePath -Encoding Byte;
# Get a cert object from the pfx bytes with the private key marked as exportable
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(
$pfxBytes,
$pfxPassword,
[Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable);
# Export a CSP blob from the cert (which is the same format as an SNK file)
[byte[]] $snkBytes = ([Security.Cryptography.RSACryptoServiceProvider]$cert.PrivateKey).ExportCspBlob($true);
# Write the CSP blob/SNK bytes to the snk file
[IO.File]::WriteAllBytes($snkFilePath, $snkBytes);
Просто запустите этот скрипт, предоставив путь к файлу pfx и пароль, и он создаст файл snk в том же каталоге, что и файл pfx (с тем же именем, но не с расширением).
powershell.exe -File pfx2snk.ps1 -pfxFilePath cert.pfx -pfxPassword "pfx password"
Или, если ваш pfx не имеет пароля (позор, позор):
powershell.exe -File pfx2snk.ps1 cert.pfx
И, если вам не повезло работать в среде, где они не позволяют выполнять сценарии PowerShell (т. Е. Только интерактивные сеансы PowerShell), то вы можете выполнить этот безобразный вкладыш из стандартного cmd.exe командная строка (при необходимости заменяя пути к файлам и пароль pfx).
powershell.exe -Command "[IO.File]::WriteAllBytes('SnkFilePath.snk', ([Security.Cryptography.RSACryptoServiceProvider](New-Object System.Security.Cryptography.X509Certificates.X509Certificate2((Get-Content 'PfxFilePath.pfx' -Encoding Byte), 'PfxPassword', [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)).PrivateKey).ExportCspBlob($true));"
Я на самом деле использую эту строку в качестве стандартной части моего процесса предварительной сборки Visual Studio, чтобы автоматизировать процесс использования тех же ключей из наших сертификатов подписи authenticode (файл pfx) для подписи строгого имени. Это не требование, но мне просто кажется, что они должны быть одинаковыми, и это подпитывает мои тенденции ОКР.
(я использую файл snk, а не оригинальный pfx, потому что у меня был «глючный» опыт использования файлов pfx для подписи строгого имени, которое @ punkcoder упоминалось в его ответе)
И, если вам интересно, у меня есть что-то вроде следующего, как часть моего процесса пост-сборки в Visual Studio, чтобы добавить сигнатуру authenticode в вывод проекта (в любом случае в конфигурациях проекта "Release").
powershell.exe -Command "Set-AuthenticodeSignature -FilePath '$(TargetPath)' -Certificate '$(SolutionDir)MyCert.pfx' -TimestampServer http://timestamp.verisign.com/scripts/timstamp.dll -HashAlgorithm sha256;"