4

手順の 1 つで証明書をインストールする必要があるインストールを開発する際に、奇妙な問題に直面しています。

この問題は、Windows Server 2008 R2 上のアカウント (IIS_IUSRS など) に証明書の秘密キー アクセスを許可することに関係しています。秘密鍵は、C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys の場所に保存されます。

カスタム C# セットアップ プロジェクトは、証明書をインポートし、インストール プロセス中に証明書の秘密キーのアカウントにアクセスできるようにします。しばらくすると (2 ~ 3 秒)、秘密鍵ファイルが MachineKeys フォルダーから自動的に削除されます。したがって、インストールされた Web アプリケーションは特定の証明書にアクセスできず、次のエラー メッセージが表示されます。

「System.Security.Cryptography.CryptographicException: キーセットが存在しません」. このエラーは Windows Server 2008 R2 でのみ発生しますが、Windows Server 2003 ではすべてが正しく機能しています。

私の質問は、秘密鍵が削除される理由と、これを行うプロセスはどれですか?

どうも

2012 年 5 月 17 日更新

説明されている問題の解決策はまだ見つかっておらず、質問した他のフォーラム (forums.asp.net、social.msdn.microsoft.com) にも回答が投稿されていません。では、この問題をさらにトラブルシューティングするために、他のリソースやアドバイスを提案できる人はいますか?

再度、感謝します

4

3 に答える 3

6

これは私にも起こっていました-私のセットアップスクリプトは証明書を追加し、PKファイルへのアクセスを許可し、アプリは機能します. その後、PowerShell エディターを閉じた後、アプリを再起動しましたが、キーセットが見つからないため失敗しました。

証明書をインポートするときに PersistKeySet フラグを追加すると、問題が修正されました。証明書と秘密キーを永続的に追加するための PowerShell コードを次に示します。

param(
    [string]$certStore = "LocalMachine\TrustedPeople",
    [string]$filename = "sp.pfx",
    [string]$password = "password",
    [string]$username = "$Env:COMPUTERNAME\WebSiteUser"
)

    function getKeyUniqueName($cert) {
         return $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
    }
    
    function getKeyFilePath($cert) {             
         return "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\$(getKeyUniqueName($cert))"
    }

$certFromFile = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($filename, $password)
$certFromStore = Get-ChildItem "Cert:\$certStore" | Where-Object {$_.Thumbprint -eq $certFromFile.Thumbprint}
$certExistsInStore = $certFromStore.Count -gt 0
$keyExists = $certExistsInStore -and ($certFromStore.PrivateKey -ne $null) -and (getKeyUniqueName($cert) -ne $null) -and (Test-Path(getKeyFilePath($certFromStore)))

if ((!$certExistsInStore) -or (!$keyExists)) {

    $keyFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet 
    $keyFlags = $keyFlags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet
    $certFromFile.Import($filename, $password, $keyFlags)

    $store = Get-Item "Cert:\$certStore"
    $store.Open("ReadWrite")

    if ($certExistsInStore) {
        #Cert is in the store, but we have no persisted private key
        #Remove it so we can add the one we just imported with the key file
        $store.Remove($certFromStore)
    }

    $store.Add($certFromFile)
    $store.Close()

    $certFromStore = $certFromFile
    "Installed x509 certificate"
}

$pkFile = Get-Item(getKeyFilePath($certFromStore))
$pkAcl = $pkFile.GetAccessControl("Access")
$readPermission = $username,"Read","Allow"
$readAccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $readPermission
$pkAcl.AddAccessRule($readAccessRule)
Set-Acl $pkFile.FullName $pkAcl
"Granted read permission on private key to web user"
于 2013-05-10T20:51:05.537 に答える
1

これがセキュリティ上の問題であることは非常に明らかです “<strong> System.Security.”. インストールを実行する権限がない場合は、秘密鍵に権限を設定して、そのサービス アカウントがアクセスできるようにする必要があります。

後で編集: Start->Run->cmd->type mmc->Select File->Add/Remove->Select Certificates->Add->Computer Account->Local. に移動します。フィールドを示しました:

ここに画像の説明を入力

[開く] -> [証明書] -> [個人] -> [証明書] -> [証明書] -> [すべてのタスク] -> [秘密キーの管理] -> [ネットワーク サービスの追加] を右クリックします。

また、このエントリをチェックして、Windows Server 2008 でこの機能がどのように機能するかを確認してください。試した後、戻ってきて、私が言ったことで問題を解決できるかどうか言ってください。

于 2012-05-08T12:38:19.727 に答える
1

http://referencesource.microsoft.com/#System/security/system/security/cryptography/x509/x509certificate2collection.cs,256は、PersistKeySet フラグがテストされる場所を示しています。PersistKeySet フラグは、https: //msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags%28v=vs.110%29.aspx で文書化されています。「PFX ファイルに関連付けられたキーは、証明書のインポート時に保持されます。」私のテクノバブルから英語への翻訳者によると、これは「X509Certificate2 コンストラクターを呼び出し、証明書が既にマシンにインストールされている可能性がある場合は、PersistKeySet フラグを含める必要がある」という意味です。これはおそらく .Import 呼び出しにも当てはまります。PowerShell の Import-PfxCertificate コマンドレットが既にこれを行っている可能性があります。ただし、受け入れられた回答が示すこと、または OP が要求したことを行っている場合は、特殊キーを含める必要があります。私たちのソリューションでは、ejegg のスクリプトのバリエーションを使用しました。構成されたすべての証明書がインストールされていることを確認するために 3 分ごとに実行されるプロセスがあり、これは現在正常に機能しているようです。

PowerShell で見られた症状は、HasPrivateKey プロパティは true ですが、PrivateKey 値自体は null です。また、C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys にある証明書のキー ファイルが削除されました。https://msdn.microsoft.com/en-us/library/aa717039(v=vs.110).aspxの FindPrivateKey ユーティリティは、ファイルが削除されるのを監視するのに役立ちました。

この非常に遅い応答で、質問の 4 歳の誕生日おめでとうございます。

于 2016-06-02T14:49:50.010 に答える