秘密鍵のアクセス許可の管理など、証明書の展開を自動化しようとしています。この質問を使用して、証明書のアクセス許可を更新するコードをいくつかまとめました。
public static SetPermissionsResult SetPermissions(X509Certificate2 certificate, string userName)
{
var account = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null);
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.MaxAllowed);
var newCertificate = store.Certificates.Find(X509FindType.FindBySerialNumber, certificate.SerialNumber, false)[0];
var rsa = newCertificate.PrivateKey as RSACryptoServiceProvider;
if (rsa == null)
{
return SetPermissionsResult.Failure;
}
rsa.PersistKeyInCsp = true;
var cspParams = new CspParameters(
rsa.CspKeyContainerInfo.ProviderType,
rsa.CspKeyContainerInfo.ProviderName,
rsa.CspKeyContainerInfo.KeyContainerName)
{
Flags =
CspProviderFlags.UseExistingKey
| CspProviderFlags.UseMachineKeyStore,
CryptoKeySecurity =
rsa.CspKeyContainerInfo.CryptoKeySecurity,
KeyNumber = (int)rsa.CspKeyContainerInfo.KeyNumber/*,
KeyPassword = password*/
};
cspParams.CryptoKeySecurity.AddAccessRule(
new CryptoKeyAccessRule(account, CryptoKeyRights.GenericRead, AccessControlType.Allow));
using (var rsa2 = new RSACryptoServiceProvider(cspParams))
{
}
return SetPermissionsResult.Success;
}
}
読み取る行using (var rsa2 = new RSACryptoServiceProvider(cspParams))
(新しい暗号化プロバイダーがインスタンス化されて新しいアクセス ルールが保持される場所) で、CryptographicException "Keyset does not exist" が発生します。
これは通常、現在のセキュリティ コンテキストに主キーへのアクセス許可がないことを意味することを経験から知っています。この可能性をトラブルシューティングするために、次のことを行いました。
System.Security.Principal.WindowsIdentity.GetCurrent()
イミディエイト ウィンドウで現在のユーザーが何を持っているかを把握する- そのユーザーが証明書の MMC スナップインでフル コントロールのアクセス許可を持っていることを確認します (そして、証明書の適切なストアを見ていることを再確認します)。
- Everyone ユーザーにフル コントロールを付与します。
- KeyPassword を使用して、または使用せずに CspParameters オブジェクトを作成しようとしました (そこにコメントが付けられていることがわかります)。
私はアイデアがありません。証明書は偽の自己署名テスト証明書であるため、チェーン内の他の証明書に権限がないことは問題ではありません。どんな助けでも大歓迎です。
アップデート:
このコードは、このステップの前にある証明書のインストール用のフラグの一部を変更することで実行できました。これで、コードが正常に実行されたように見えますが、MMC で確認できる目に見える効果はありません。