通过删除多个RSA文件清除我的MachineKeys文件夹,而不触及IIS文件

时间:2015-12-30 10:17:19

标签: iis rsa x509certificate2

我目前正在服务器上使用实例化证书运行IIS。

通过执行此代码,例如:

X509Certificate2 myX509Certificate = new 
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate, 
X509KeyStorageFlags.Exportable | 
X509KeyStorageFlags.MachineKeySet | 
X509KeyStorageFlags.PersistKeySet);

代码工作正常。但我在计算机上遇到问题,在以下文件夹中:

  

C:\ ProgramData \微软\加密\ RSA \ MachineKeys的

继续在该文件夹上添加3KB RSA文件。现在,我有超过一百万个文件,比如那些:

enter image description here

我想删除这些文件,但是:

  • IIS使用其中一个来加密密码,或者可能用于其他密码 目的,我不知道哪一个,
  • 删除这么大的文件夹需要时间(如天)

    1. 是否有一种简单的方法可以反复创建这些文件? (如果我没有提及" MachineKeySet"在实施我的证书时,这不会起作用)
    2. 如果没有,有没有办法删除创建的文件而不删除IIS文件?
    3. 有没有办法检测IIS使用哪些文件?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

你有一些工作要做。首先,每当您需要访问PFX文件时,* 绝不 *实例化X509Certificate2对象。这是非常糟糕的想法。这会导致在MachineKeys文件夹中生成新的密钥文件。相反,您必须将证书安装到本地证书存储一次,然后引用已安装的证书。

使用X509Store.Add()方法将certficate安装到本地商店:

X509Certificate2 myX509Certificate = new 
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate, 
X509KeyStorageFlags.MachineKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(myX509Certificate);
store.Close()

下次需要访问证书和私钥时,请使用相同的X509Store类,如下所示:

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 myCert = store.Certificates.Find(blablabla);
store.Close()

而不是“blablabla”,请指定搜索过滤器:X509Certificate2Collection.Find()。您可以使用各种过滤器选项来查找证书。最常用的是指纹。

关于大文件夹。如果您确定LocalMachine \ My商店中没有其他证书,您只需清除所有内容,然后使用上面的代码安装证书。

答案 1 :(得分:2)

遇到了同样的问题,就像我在其他资料中所读到的那样,我非常害怕删除某些内容,因为其中存在一些系统关键文件。删除这些少数文件,最终可能会导致IIS或其他软件混乱。

因为那里有8'000'000个文件,所以我什至无法打开该文件夹-我所做的是用C#编写一个小程序,该程序由OWNER判断删除文件-创建文件的用户!如果它们是由IIS用户创建的,则这样做是安全的(请确保您了解自己在做什么!)

        var userNameToDeleteBy = "IIS_App_Pool_User_Goes_here!";

        var allFiles = (new DirectoryInfo(Directory.GetCurrentDirectory()).EnumerateFiles());

        var i = 0;

        foreach (var file in allFiles)
        {

            var fname = file.FullName;
            string user = System.IO.File
                .GetAccessControl(fname)
                .GetOwner(typeof(System.Security.Principal.NTAccount))
                .ToString();

            if(user.Contains(userNameToDeleteBy))
            {
                File.Delete(fname);
                i++;
            }

            //output only every 1k files, as this is the slowest operation
            if (i % 1000 == 0) Console.WriteLine("Deleted: " + i); 
        }

此外,如果您真的需要从文件中加载证书,这是如何使文件夹无垃圾的答案:

Prevent file creation when X509Certificate2 is created?

答案 2 :(得分:0)

这是一个Powershell脚本,它删除特定应用程序池用户拥有的所有机器密钥。

它与@halloweenlv制作的C#程序基本相同(powershell脚本似乎更实用)

param(
  [ValidateNotNullOrEmpty()]
  [Parameter(Mandatory=$true)]
  [string] $ApplicationPoolName,
  [string] $MachineKeysDirectory = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys"
)

$nrOfKeysDeleted = 0;

foreach ($keyPath in [IO.Directory]::EnumerateFiles($MachineKeysDirectory)) {
  $owner = Get-Acl -Path $keyPath | Select-Object -ExpandProperty "Owner";

  if ($owner -eq "IIS APPPOOL\$ApplicationPoolName") {
    [System.IO.File]::Delete($keyPath)
    $nrOfKeysDeleted++;
  }

  if ($nrOfKeysDeleted  -gt 0 -and $nrOfKeysDeleted % 1000 -eq 0) {
    Write-Output -Verbose "Deleted $nrOfKeysDeleted keys";
  }
}

Write-Output -Verbose "Deleted $nrOfKeysDeleted keys";

此目录中的机器密钥是系统文件。如前所述,某些文件对于系统至关重要,因此简单地删除所有内容并不是一个好主意。

性能还可以,但不是很好。在我的服务器上,删除1000个密钥大约需要5秒钟。一百万个密钥大约需要一个小时半。