10

次のことを実行するには、ビルド後のイベントを作成する必要があります。

sn -i MyKey.pfx MyKeyContainerName
tlbimp $(ConfigurationName)\MyCom.tlb /out:$(ConfigurationName)\NETMyCom.dll /keycontainer:MyKeyContainerName
sn -d MyKeyContainerName

Visual Studioが最初のステートメントを実行すると、パスワードが必要になり、ユーザーが指定して失敗するまで待機します。

Microsoft(R).NET Frameworkストロングネームユーティリティバージョン2.0.50727.42Copyright(c)MicrosoftCorporation。全著作権所有。

PKCS#12キーファイルのパスワードを入力してください:mykey.pfxのPKCS#12blobの解析に失敗しました-ハンドルが無効です。

snコマンドライン引数を使用してパスワードを指定しようとしましたが、その方法がわかりませんでした。

助けてください。

よろしく、ヒルミ。

4

7 に答える 7

6

残念ながら、ここで言及されているアプローチは私にとってはうまくいきませんでした。docker コンテナーにいくつかの pfx を登録する必要があります。

そこで、 RSACryptoServiceProvidersn.exe -i <infile> <container>を使用して C# でコマンドを再開発し ました。ソースとアプリは GitHub のSnInstallPfxプロジェクトにあります。

SnInstallPfxアプリは、PFX キーとそのパスワードを受け入れますキー コンテナー名 (VS_KEY_*) を自動的に計算し (MSBuild ソース コードから借用)、厳密な名前の CSP にインストールします。

使用法:

SnInstallPfx.exe <pfx_infile> <pfx_password>
于 2019-11-09T16:11:13.000 に答える
3

私のように、ビルドに TFS または MSBUILD を使用していない場合は、他に少なくとも 2 つの方法があります。

a) スクリプトから sn.exe を実行し、パスワードを stdin に書き込みます

C# の例については、こちらを参照してください。

注:sn.exeの.NET4バージョンでは、外部プロセスとして実行することは不可能のようです(少なくともWindows XPでは)、パスワードを標準入力に書き込みます(C#でpython +で試しましたが、sn.exeはパスワードの入力を待たずに終了する)。

b) 既にインストールされている pfx を使用して、sn.exe を使用してパスワードに再署名します。

pfx ファイルを既にインストールしている場合は、コンテナー名を知っている可能性があります (通常、Visual Studio は VS_KEY_ABAB1234ABAB1234 のような名前を使用します)。

私のように、コンテナー名がわからない、または覚えていない場合は、pfx ファイルを再インストールしてください。

sn -i myPfxFile VS_KEY_ABAB1234ABAB1234

sn.exe は、証明書を pfx ファイルにインストールするため、パスワードの入力を求めます。

次に、パスワードのプロンプトを表示せずに、sn.exe でアセンブリに再署名させることができます。

sn -Rca myAssembly.dll myVSkey

相互作用が必要ないため、上記はビルドスクリプトで使用できます:-)

NB 署名が実際に機能することを確認することを忘れないでください。

sn -v myAssembly.dll
于 2012-06-01T14:45:03.427 に答える
0

WinAPI を使用すると、次のように実行できます。

Param(
    [string]  $Password ,
    [string] $CertFilePath 
)

function ExecuteCommand([string]$message)
{
    try{
    foreach ($char in [char[]]$message) {
    [void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, [int]$char, 0) 
    }
    [void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, 13, 0)
    Sleep 3
    }catch{
    }
}

Add-Type -Name ConsoleUtils -Namespace WPIA -MemberDefinition @'
[DllImport("user32.dll")]
public static extern int PostMessage(int hWnd, uint Msg, int wParam, int lParam);
public const int WM_CHAR = 0x0102;
'@

$Win32API = Add-Type -Name Funcs -Namespace Win32 -PassThru -MemberDefinition @'
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

    [DllImport("kernel32.dll")]
  public static extern uint GetLastError();
'@

[System.Reflection.Assembly]::Load("Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
[System.Reflection.Assembly]::Load("Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object Microsoft.Build.Tasks.ResolveKeySource
$publish.KeyFile=$CertFilePath
try
{
        $publish.Execute()
}
catch{
        $VsKey= [regex]::match($error[0].Exception,'VS_KEY_[A-F0-9]+').Value
        $VsKey =$VsKey -replace "`n|`r"
}
$quotedCertPath='"'+$CertFilePath+'"'
Write-Host 'VsKey='$VsKey

start cmd
$proc=Get-Process | Where-Object {$_.Name -like "*cmd*"}
$proc.MainWindowTitle
$handle = $proc.MainWindowHandle
'1:'+$handle
if($handle -eq 0){
    $handle=$Win32API::FindWindow([IntPtr]::Zero, 'C:\WINDOWS\system32\cmd.exe')
    '2:'+$handle
}   
if($handle -eq 0){
    $handle=$Win32API::FindWindow('C:\WINDOWS\system32\cmd.exe',       [IntPtr]::Zero)
    '3:'+$handle
}
if($handle -eq 0){
    $proc2 = Start-Process cmd.exe -PassThru
    $proc2
    Get-Process -id $proc2.Id
    Sleep 3;
    $handle = (Get-Process -id $proc2.Id).MainWindowHandle
    $handle
    $proc.MainWindowHandle
    $proc.Refresh()
    Sleep 3;
    $proc.MainWindowHandle
}


Write-Host 'Handle='$handle

ExecuteCommand 'echo Starting > d:\a\1\s\Authenticode\log.txt'  
$SnCommand=[string]::Format(".\sn.exe -i {0} {1}",$quotedCertPath,$VsKey)
ExecuteCommand $SnCommand
ExecuteCommand $Password
于 2020-06-19T14:36:49.507 に答える
0

これを自動化する必要があり、この質問を見つけました。この回答に続いて(@Thomas Rijsewijkに感謝します)、私はそれの私のバージョンを書きました:

# Start the sn.exe process
Start-Process $SnExePath -ArgumentList "-i $PfxCertificatePath $LocalContainerName" -NoNewWindow
# Wait for the process to start
Start-Sleep 2
# This workaround allows to forward the password to the standard input
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("$($PfxCertificatePassword){ENTER}")
Start-Sleep 2
# This ENTER is to return from the sn.exe process
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

-Waitコマンドのスイッチを使用してStart-processも問題は解決しませんでした。これは、PS スクリプトが sn.exe プロセスの終了を待ってからパスワードを転送していたためです。

于 2018-11-30T12:09:34.460 に答える