通过删除多个 RSA 文件而不触及 IIS 文件来清理我的 MachineKeys 文件夹
Clean my MachineKeys folder by removing multiple RSA files without touching IIS ones
我目前 运行 我的服务器上的 IIS 使用实例化证书的应用程序。
通过执行此代码,例如:
X509Certificate2 myX509Certificate = new
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
代码运行良好。但是我在我的电脑上遇到了一个问题,在以下文件夹中:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
3KB RSA 文件不断添加到该文件夹中。现在,我有超过一百万个这样的文件:
我想删除那些文件,但是:
- IIS 使用其中之一来加密密码,或者可能用于其他
目的,我不知道是哪一个,
删除这么大的文件夹可能需要一些时间(比如几天)
- 有没有一种简单的方法可以避免一次又一次地创建这些文件? (如果我在实例化我的证书时不提及 "MachineKeySet",这将不起作用)
- 如果没有,有没有办法在不删除 IIS 文件的情况下删除创建的文件?
- 有没有办法检测 IIS 使用了哪些文件?
在此先感谢您的帮助。
有一些工作给你。首先,您*绝不能*每次需要访问 PFX 文件时实例化 X509Certificate2
对象。这是非常糟糕的主意。这会导致在 MachineKeys 文件夹中生成一个新的密钥文件。相反,您必须将证书安装到本地证书存储一次,然后引用安装的证书。
使用X509Store.Add()
方法将证书安装到本地商店:
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
class,如下所示:
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 存储中没有其他证书,您可以简单地清除所有内容,然后使用上面的代码安装您的证书。
有同样的问题,并且非常害怕删除一些东西,正如我在其他来源上看到的那样,那里有一些系统关键文件。通过删除这几个,您最终可能会搞砸 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?
这是一个 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 秒。一百万个密钥大约需要一个半小时。
我目前 运行 我的服务器上的 IIS 使用实例化证书的应用程序。
通过执行此代码,例如:
X509Certificate2 myX509Certificate = new
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
代码运行良好。但是我在我的电脑上遇到了一个问题,在以下文件夹中:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
3KB RSA 文件不断添加到该文件夹中。现在,我有超过一百万个这样的文件:
我想删除那些文件,但是:
- IIS 使用其中之一来加密密码,或者可能用于其他 目的,我不知道是哪一个,
删除这么大的文件夹可能需要一些时间(比如几天)
- 有没有一种简单的方法可以避免一次又一次地创建这些文件? (如果我在实例化我的证书时不提及 "MachineKeySet",这将不起作用)
- 如果没有,有没有办法在不删除 IIS 文件的情况下删除创建的文件?
- 有没有办法检测 IIS 使用了哪些文件?
在此先感谢您的帮助。
有一些工作给你。首先,您*绝不能*每次需要访问 PFX 文件时实例化 X509Certificate2
对象。这是非常糟糕的主意。这会导致在 MachineKeys 文件夹中生成一个新的密钥文件。相反,您必须将证书安装到本地证书存储一次,然后引用安装的证书。
使用X509Store.Add()
方法将证书安装到本地商店:
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
class,如下所示:
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 存储中没有其他证书,您可以简单地清除所有内容,然后使用上面的代码安装您的证书。
有同样的问题,并且非常害怕删除一些东西,正如我在其他来源上看到的那样,那里有一些系统关键文件。通过删除这几个,您最终可能会搞砸 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?
这是一个 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 秒。一百万个密钥大约需要一个半小时。