42

マイクロソフトは、理解するのが難しい認定ジャングルを作成したようです。

  • Microsoft X.509 証明書 (.cer)
  • 個人情報交換 (.pfx)
  • アセンブリ署名キー属性 (.snk)

    1. pfx または cer に基づいて snk ファイルを作成することをお勧めしますか? (可能かどうかはわかりません。可能であれば、どのように行われますか?)

    2. アセンブリはパスワードで保護された pfx で署名できますが、代わりに snk で署名されていない限り、厳密な名前ではないようです。ただし、snk にはパスワード保護がありません。どちらを使用する方が安全ですか?私は自分のプロジェクトで唯一の開発者であるため、マルチ開発者の安全な環境の問題はありませんが、最善のアプローチを知りたいです。

どうもありがとう、

4

3 に答える 3

41

言及されたファイルの種類について少し説明します。

  • .cer -ファイルは X.509 証明書です
  • .pfx -ファイルは、パスワードベースの対称キーを使用して暗号化された X.509 証明書です。PKCS #12 (Wikipedia)も参照してください。
  • .snk - ファイルには RSA キーのみが含まれます (パブリック/プライベートまたはパブリックのみ)

.pfxファイルまたは.snkファイルを使用してアセンブリに署名するかどうかは関係ありません。どちらの方法でも厳密な名前が付けられます。もちろん、RSA キーを暗号化された証明書 ( .pfx ) として保存する方が、暗号化されていないキー ( .snk )だけを保存するよりも安全です。

class を使用して、コードでこれらのファイルからキーを簡単に抽出できますSystem.Security.Cryptography.X509Certificates.X509Certificate2

.pfxからキーを抽出するには:

/// <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);
}

privateKey.ExportCspBlob(false)公開鍵のみを抽出するために使用してください! (例: アセンブリの遅延署名用)

于 2012-07-12T22:09:21.690 に答える
32

pfx からの公開鍵のみを使用して snk ファイルを生成するには:

sn -p keypair.pfx key.snk

私は常に .pfx ファイルよりも snk ファイルを使用することを好んでいました。

于 2012-03-27T22:34:21.483 に答える
18

@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 ファイルのパスとパスワードを指定してそのスクリプトを実行するだけで、pfx ファイルと同じディレクトリに (拡張子以外は同じ名前で) snk ファイルが作成されます。

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 ファイル) から同じキーを使用して厳密な名前の署名を行うプロセスを自動化しています。それは要件ではありませんが、それらが同じであることは私には理にかなっているように思え、それは私の強迫性障害の傾向を助長します.

(@ punkcoderが彼の回答で言及した強力な名前署名にpfxファイルを使用した「バグのある」経験があったため、元のpfxではなくsnkファイルを使用します)

また、興味がある場合は、Visual Studio でのビルド後のプロセスの一部として、次のようなものを用意して、Authenticode 署名をプロジェクト出力に追加します (「リリース」プロジェクト構成で)。

powershell.exe -Command "Set-AuthenticodeSignature -FilePath '$(TargetPath)' -Certificate '$(SolutionDir)MyCert.pfx' -TimestampServer http://timestamp.verisign.com/scripts/timstamp.dll -HashAlgorithm sha256;"
于 2016-09-17T17:45:13.763 に答える