ssl 创建X509Certificate2时是否阻止文件创建?

13z8s7eq  于 11个月前  发布在  其他
关注(0)|答案(5)|浏览(95)

我们在ASP.NET应用程序中创建了一个X509 Certificate 2对象来进行周期性的传出连接。每次创建这些证书时,都会在以下位置创建一个新文件:
C:\Website\Website\Website\Website
这个文件夹现在有400万个文件从来没有被清理过。
new X509Certificate2(certainty,p12Pwd,X509Keywords Flags. MachineKeySet);
//no X509KeySet Flags. PersistKeySet
但这并没有帮助--仍然会在每个呼叫上获得2KB文件。
当我看到this answer时,我抱了很大的希望,但这是一个2008 R2服务器,临时文件不是0字节,所以这似乎是一个不同的情况。
如何使用X509 Certificate 2而不填满磁盘?

ndh0cuux

ndh0cuux1#

我在我们的服务器上也有同样的问题。我现在找到的最好方法是从我的代码中删除文件。

using System;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Byte[] bytes = File.ReadAllBytes(@"D:\tmp\111111111111.p12");
            X509Certificate2 x509 = new X509Certificate2(bytes, "qwerty", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            var privateKey = x509.PrivateKey as RSACryptoServiceProvider;
            string uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName;
            x509.Reset();

            File.Delete(string.Format(@"C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\{0}", uniqueKeyContainerName));
        }
    }
}

字符串

8yoxcaq7

8yoxcaq72#

Use .NET 4.6
X509 Certificate 2从.NET Framework 4.6开始实现IDisposable接口;在.NET Framework的早期版本中,X509 Certificate 2类不实现此接口,因此Dispose方法不存在。

qq24tv8q

qq24tv8q3#

为了重现你的问题,我创建了这个示例代码。我的测试环境是Windows 8.1 64位,应用程序是用.NET 4.5编写的。

using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var certBytes = File.ReadAllBytes(@"c:\cert.p12");
            var p12Pwd = "somepassword";

            for (var i = 0; i < 1000; i++)
            {
                var cert = new X509Certificate2(certBytes, p12Pwd, X509KeyStorageFlags.MachineKeySet);

                // this line helped keep filesize from growing   
                // cert.Reset(); 
            }
        }
    }
}

字符串
我感到震惊的是,C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys的文件大小上升到2MB。然后应用程序退出,文件大小下降到20K(这可能是它的起始大小)。
然后我添加了cert.Reset();(我在上面的代码中注解了它)。当你不再需要X509Certificate2示例时,应该调用它。之后,C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys的文件大小在20K和22K之间波动。
所以我的建议是当你不再需要X509Certificate2示例时调用cert.Reset();

xesrikrc

xesrikrc4#

我在我们的服务器上也遇到了同样的问题。目前我发现的最好的方法是通过脚本删除文件(有用的除外)。
例外清单:

  • 微软互联网信息服务器-> 2319 c42033 a5 ca 7 f44 e731 bfd 3fa 2b 5.
  • ... class ='class10'网络架构配置键-> d 6d 986 f09 a1 ee 04 e24 c949879 fdb 506 c->数据库管理员登录
  • 公司名称:深圳市捷联科技有限公司工作地点:广东省深圳市
  • WMSvc证书密钥容器-> bedbf 0 b4 da 5 f8061 b6444 baedf 4c 00 b1证书密钥容器-> bedbf 0 b4 da 5 f8061 b644 baedf 4c 00 b1证书密钥容器-> bedbf 4c 00 b1证书密钥容器
  • 配置键-> 98 c 01 ec 4 e9 e8 b34824 aa 2...
  • 微软IIS服务器->微软IIS服务器->
  • ... class ='class10'安全密钥集1->安全密钥集2->安全密钥集3->安全密钥集4->安全密钥集5->安全密钥集6->安全密钥集7
  • https://forums.whirlpool.net.au/archive/1683713

通过https://forums.iis.net/t/1224708.aspx?C+ProgramData+Microsoft+Crypto+RSA+MachineKeys+is+filling+my+disk+space
此解决方案仍然是一个修补程序。最好不要在MachineKeys文件夹中生成文件。

4xrmg8kj

4xrmg8kj5#

我试着使用我在这里找到的建议,但在我的情况下,它最终失败了。虽然文件夹开始变少,但一些垃圾是随机留在那里。
我的情况:我正在加载证书以在HttpClient中使用,似乎它卡在了HttpClient中。
我已经实现了所有东西的超类(X509 Certificate 2、HttpClient、HttpClient)来简化这项工作,但是不知道为什么Dispose()方法没有被调用。
也许它与HttpClient池有关,但它似乎被设计为失败-无论你做什么,总会有东西在另一个地方失败。
所以我决定写一个服务,删除它们后,一段时间,最后我设法保持文件夹干净。
这里是:

public class AutoResetX509Certificate2 : X509Certificate2
{
    string autoGeneratedFile = "";
    const string keyFolder = @"C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys";

    public AutoResetX509Certificate2(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) : base(rawData, password, keyStorageFlags)
    {
        var uniqueName = ((System.Security.Cryptography.RSACng)this.PrivateKey).Key.UniqueName;
        autoGeneratedFile = Path.Combine(keyFolder, uniqueName);
        AddFileToDeletion(autoGeneratedFile);
        StartAutoResetService();
    }

    public AutoResetX509Certificate2(byte[] rawData) : base(rawData)
    {
        var uniqueName = ((System.Security.Cryptography.RSACng)this.PrivateKey).Key.UniqueName;
        autoGeneratedFile = Path.Combine(keyFolder, uniqueName);
        AddFileToDeletion(autoGeneratedFile);
        StartAutoResetService();
    }

    protected override void Dispose(bool disposing)
    {
        StopAutoResetService();
        base.Dispose(disposing);
    }

    private void AddFileToDeletion(string path)
    {
        var folder = Path.Combine(keyFolder, "!deletionTrack");
        Directory.CreateDirectory(folder);
        var fi = new FileInfo(path);
        var file = Path.Combine(folder, fi.Name);
        File.WriteAllText(file, "");
    }

    //======================= AutoResetService

    static System.Timers.Timer timer = new() { Enabled = false, Interval = 5000 };

    static bool isTimerBusy = false;

    internal static void StartAutoResetService()
    {
        lock (timer)
        {
            if (!timer.Enabled)
            {
                timer.Elapsed += Timer_Elapsed;
                timer.Enabled = true;
            }
        }
    }

    internal static void StopAutoResetService()
    {
        lock (timer)
        {
            timer.Enabled = false;
            timer.Elapsed -= Timer_Elapsed;
        }
    }

    private static void RunAutoReset()
    {
        var folder = Path.Combine(keyFolder, "!deletionTrack");
        var di = new DirectoryInfo(folder);
        if (di.Exists)
        {
            var olders = di.GetFiles().Where(fi => DateTime.Now.Subtract(fi.CreationTime).TotalSeconds > 30).ToList();
            foreach (var old in olders)
            {
                var certPath = Path.Combine(keyFolder, old.Name);
                if (File.Exists(certPath)) File.Delete(certPath);
                old.Delete();
            }
        }
    }

    private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (isTimerBusy) return;
        isTimerBusy = true;
        try
        {
            RunAutoReset();
        }
        catch(Exception)
        {
            //implement your logger here if you need it.
        }
        finally
        {
            isTimerBusy = false;
        }
    }
}

字符串
您只需要使用该类(AutoResetX 509 Certificate 2)而不是X509 Certificate 2加载证书。

//example:
var clientCert = new AutoResetX509Certificate2(pfxBytes, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);


注意我实现了我需要的两个构造函数,如果你需要另一个,你可以像这两个一样实现。

相关问题