使 CRL 缓存失效

本文关键字:失效 缓存 CRL | 更新日期: 2023-09-27 18:33:34

有没有办法立即使CRL(证书吊销列表(缓存失效,导致客户端再次下载CRL?

我想在 C# 中实现它,而无需诉诸命令行"certutil.exe"。

更好的是能够设置失效时间(如UtcNow + 12小时(

使 CRL 缓存失效

我已经实现了这样的解决方案,它每 x 小时更新一次客户端计算机上的 CRL 缓存,具体取决于调度程序设置。您可以在此处阅读有关 CRL 的信息:http://social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx

CRL 缓存存储在客户端计算机上的特殊文件夹中,由存储在"元数据"和"内容"文件夹中的两个文件组成。这些文件夹放置在"C:''Documents and Settings{用户名}''Application Data''Microsoft''CryptnetUrlCache"中,每台计算机的缓存位置为"%WINDIR%''System32''config''SystemProfile''Application Data''Microsoft''CryptnetUrlCache"。Cahce 文件以 CRL url 的 MD5 哈希和命名。文件夹"元数据"中的文件包含一些常量数据,上次更新日期,CRL URL,CRL文件大小等。"内容"文件夹中的文件是CRL文件本身,与"元数据"中的文件具有相同的名称。我解析元文件,检查它是否无效并通过CRL url加载新的CRL文件,将其放置到"内容"文件夹并重建元数据文件。我使用BouncyCastle库来实现这些目的。作为调度库,我使用 Quartz.Net。

我知道

您不想使用certutil.exe但是这样您就可以在应用程序中运行它而不会显示cmd窗口,如果这是您不想要的。

public bool ClearCRLCache()
{
    var pw = new ProcessWrapper();
    var result = pw.Start("certutil.exe", "-urlcache * delete");
    // -2147024637 is the exitcode when the urlcache is empty
    return (result == 0 || result == -2147024637);
}

类 ProcessWrapper:

public class ProcessWrapper
{
    /// <summary>
    /// Output from stderr
    /// </summary>
    public string StdErr { get; private set; }
    /// <summary>
    /// Output from stdout
    /// </summary>
    public string StdOut { get; private set; }
    /// <summary>
    /// Starts a process
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command)
    {
        return Start(command, "");
    }
    /// <summary>
    /// Starts a process with commandline arguments
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <param name="arguments">Commanline arguments for the process</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command, string arguments)
    {
        return Start(command, arguments, "");
    }
    /// <summary>
    /// Starts a process with commandline arguments and working directory
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <param name="arguments">Commanline arguments for the process</param>
    /// <param name="workingDirectory">Working directory for the process</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command, string arguments, string workingDirectory)
    {
        StdErr = "";
        StdOut = "";
        var proc = new Process();
        proc.StartInfo.FileName = command;
        proc.StartInfo.Arguments = arguments;
        proc.StartInfo.WorkingDirectory = workingDirectory;
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.RedirectStandardError = true;
        proc.EnableRaisingEvents = true;
        proc.StartInfo.CreateNoWindow = true;
        // Write messages from stderr to StdErr property
        proc.ErrorDataReceived += (sender, e) =>
        {
            StdErr += e.Data + Environment.NewLine;
        };
        // Write messages from stdout to StdOut property
        proc.OutputDataReceived += (sender, e) =>
        {
            StdOut += e.Data + Environment.NewLine;
        };
        proc.Start();
        proc.BeginErrorReadLine();
        proc.BeginOutputReadLine();
        proc.WaitForExit();
        return proc.ExitCode;
    }
}