C# 如何从pfx/cer创建snk?
微软似乎创造了一个难以理解的认证丛林C# 如何从pfx/cer创建snk?,c#,.net,x509certificate,pfx,snk,C#,.net,X509certificate,Pfx,Snk,微软似乎创造了一个难以理解的认证丛林 Microsoft X.509证书(.cer) 个人信息交换(.pfx) 程序集签名密钥属性(.snk) 是否建议基于pfx或cer创建snk文件? (不确定这是否可能,如果可能,怎么做?) 虽然可以使用受密码保护的pfx对程序集进行签名,但是 但似乎不是很有名,除非是与snk签署的 相反但是snk没有密码保护。哪个更安全 使用?因为我是我项目中唯一的开发者,所以我没有 多开发者安全环境问题,但仍希望 知道什么是最好的方法 非常感谢,要从pfx生成sn
- Microsoft X.509证书(.cer)
- 个人信息交换(.pfx)
- 程序集签名密钥属性(.snk)
- 是否建议基于pfx或cer创建snk文件? (不确定这是否可能,如果可能,怎么做?)
- 虽然可以使用受密码保护的pfx对程序集进行签名,但是 但似乎不是很有名,除非是与snk签署的 相反但是snk没有密码保护。哪个更安全 使用?因为我是我项目中唯一的开发者,所以我没有 多开发者安全环境问题,但仍希望 知道什么是最好的方法
非常感谢,要从pfx生成snk文件:
sn -p keypair.pfx key.snk
我一直非常喜欢使用snk文件而不是.pfx文件,因为它们似乎没有那么多问题。关于您提到的文件类型的一点说明:
- .cer文件是X.509证书
- .pfx文件是使用基于密码的对称密钥加密的X.509证书,另请参见
- .snk文件仅包含RSA密钥(公用/专用或仅公用)
System.Security.Cryptography.X509Certificates.X509Certificate2
轻松地从代码中的这些文件中提取密钥
要从.pfx中提取密钥,请执行以下操作:
//
///将.pfx文件转换为.snk文件。
///
///.pfx文件数据。
///.pfx文件密码。
///.snk文件数据。
公共静态字节[]Pfx2Snk(字节[]pfxData,字符串pfxPassword)
{
//加载.pfx
var cert=新的X509Certificate2(pfxData、pfxPassword、X509keystrageFlags.Exportable);
//创建.snk
var privateKey=(rsacyptoserviceprovider)cert.privateKey;
返回privateKey.ExportCspBlob(true);
}
使用
privateKey.exportCsplob(false)
仅提取公钥!(例如,对于程序集的延迟签名)以下是his中提供的相同方法,但已转换为PowerShell脚本(pfx2snk.ps1)。
只需运行提供pfx文件路径和密码的脚本,它将在与pfx文件相同的目录中创建一个snk文件(除了扩展名外,名称相同)
或者,如果您的pfx没有密码(羞耻,羞耻):
而且,如果您不幸在不允许执行PowerShell脚本的环境中工作(即仅限交互式PowerShell会话),那么您可以从标准cmd.exe命令行(根据需要替换文件路径和pfx密码)执行这个难看的一行代码
实际上,我将这一行代码作为VisualStudio预构建过程的标准部分使用,以自动化使用来自authenticode签名证书(pfx文件)的相同密钥进行强名称签名的过程。这不是一个要求,但对我来说,它们应该是一样的,这似乎是有道理的,这助长了我的强迫症倾向
(我使用snk文件而不是原始的pfx文件,因为我有过使用pfx文件进行强名称签名的“错误”体验,这在他的回答中提到过)
而且,如果您感兴趣,我在VisualStudio中的后期构建过程中有如下内容,可以将authenticode签名添加到项目输出中(无论如何,在“发布”项目配置中)
这在VS2010中给了我一个错误:密钥文件“key.snk”不包含公钥/私钥对。您正在使用的pfk可能不完整,我在使用Verisign提供的.pfk文件时遇到了这个问题,特别是在它们提供.pfk、.cer、,和.pfx文件分开。p使其仅在snk中存储证书的公共部分。由于您没有私钥,因此不能使用生成的snk进行签名,除了延迟签名,延迟签名不会改变结束…您可以使用
sn-k keypair.snk
生成公钥和私钥。我一点也不知道私钥是从哪里来的,但至少它对我来说是有用的。(很抱歉死掉了这个线程)@Slampisko-FYI,来自-k
选项“生成一个新的…密钥”。这就是为什么您不必引用已发布的现有.pfxI。我在VB中这样做是为了见鬼。这对我不起作用。我在尝试在VS2013中使用时出现加密错误。编辑队列已满,或者我要在上面添加:使用System.Security.Cryptography.X509Certificates;使用System.Security.Cryptography;谢谢出于某种原因,最后一行没有为我输出文件,而是将其替换为:Set Content-Path“$snkFilePath”-Value$snkBytes-Encoding Byte
修复了该问题。该文件似乎放在我运行脚本的上方目录中。我将脚本的最后一行更改为:[IO.File]::writealBytes((Join Path-Path(Get Location)-ChildPath$snkFileName),$snkBytes);
/// <summary>
/// Converts .pfx file to .snk file.
/// </summary>
/// <param name="pfxData">.pfx file data.</param>
/// <param name="pfxPassword">.pfx file password.</param>
/// <returns>.snk file data.</returns>
public static byte[] Pfx2Snk(byte[] pfxData, string pfxPassword)
{
// load .pfx
var cert = new X509Certificate2(pfxData, pfxPassword, X509KeyStorageFlags.Exportable);
// create .snk
var privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
return privateKey.ExportCspBlob(true);
}
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);
powershell.exe -File pfx2snk.ps1 -pfxFilePath cert.pfx -pfxPassword "pfx password"
powershell.exe -File pfx2snk.ps1 cert.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));"
powershell.exe -Command "Set-AuthenticodeSignature -FilePath '$(TargetPath)' -Certificate '$(SolutionDir)MyCert.pfx' -TimestampServer http://timestamp.verisign.com/scripts/timstamp.dll -HashAlgorithm sha256;"