有没有办法立即使 CRL(证书吊销列表)缓存失效,导致客户端再次下载 CRL?
我想在 C# 中实现它而不求助于命令行“certutil.exe”。
更好的是能够设置失效时间(如 UtcNow + 12hours)
有没有办法立即使 CRL(证书吊销列表)缓存失效,导致客户端再次下载 CRL?
我想在 C# 中实现它而不求助于命令行“certutil.exe”。
更好的是能够设置失效时间(如 UtcNow + 12hours)
我已经实现了这样的解决方案,它每 x 小时更新一次客户端机器上的 CRL 缓存,具体取决于调度程序设置。您可以在此处阅读 CRL:http: //social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx
CRL 缓存存储在客户端计算机上的特殊文件夹中,由存储在 Metadata 和 Content 文件夹中的两个文件组成。这些文件夹位于“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 库用于这些目的。
我知道你不想使用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;
}
}