C# 以编程方式安装证书吊销列表(CRL)

C# 以编程方式安装证书吊销列表(CRL),c#,powershell,scripting,vbscript,batch-file,C#,Powershell,Scripting,Vbscript,Batch File,我需要每周下载和安装大约50个CRL,并将它们安装在几个Windows服务器上。下载是最简单的部分,有没有办法编写CRL导入过程的脚本?我不知道如何通过脚本完成。 你会写C代码吗?如果我理解你想做什么,你将使用函数和结构 这里有一个例子;相应的CRL导入类似 附录: 指出Win32 API(如CryptoUIWizimport)不能直接从PowerShell访问,然后介绍了一种可能的解决方法:在PowerShell脚本中,动态生成并编译执行P/Invoke操作的C#代码,然后运行生成的程序集。这

我需要每周下载和安装大约50个CRL,并将它们安装在几个Windows服务器上。下载是最简单的部分,有没有办法编写CRL导入过程的脚本?

我不知道如何通过脚本完成。 你会写C代码吗?如果我理解你想做什么,你将使用函数和结构

这里有一个例子;相应的CRL导入类似

附录

指出Win32 API(如CryptoUIWizimport)不能直接从PowerShell访问,然后介绍了一种可能的解决方法:在PowerShell脚本中,动态生成并编译执行P/Invoke操作的C#代码,然后运行生成的程序集。这将允许您严格地从powershell脚本执行CryptUiWizImport,尽管这将是一个非常奇特的脚本

在Powershell中有一个表示证书存储的
证书:
提供程序。可以通过标准cmdlet对其进行操作,这样您就可以在某处集成吊销列表。我只是不太了解Windows如何处理证书,因此这里没有任何进一步的帮助。

Hm。有什么理由不使用certutil.exe实用程序吗?我可以通过运行以下命令将证书吊销列表导入相应的存储:

certutil -addstore CA <FileName>.crl
certutil-addstore CA.crl
这是我的最后一个源代码(对公众稍微删减)-但应该有用。我不会改变被接受的答案,但我真的希望这会有所帮助(就像投票表决问题和答案一样!)

注意:这会将CRL或常规证书导入本地计算机受信任的根存储。在调用CertOpenStore中将下面的
CERT\u SYSTEM\u STORE\u LOCAL\u MACHINE
更改为
CERT\u SYSTEM\u STORE\u CURRENT\u USER
,将其更改为适用于当前用户商店

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication2
{
  class Program
  {
    public struct CRYPTUI_WIZ_IMPORT_SRC_INFO
    {
      public Int32 dwSize;
      public Int32 dwSubjectChoice;
      [MarshalAs(UnmanagedType.LPWStr)]public String pwszFileName;
      public Int32 dwFlags;
      [MarshalAs(UnmanagedType.LPWStr)]public String pwszPassword;
    }

    [DllImport("CryptUI.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern Boolean CryptUIWizImport(
      Int32 dwFlags,
      IntPtr hwndParent,
      IntPtr pwszWizardTitle,
      ref CRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
      IntPtr hDestCertStore
    );

    [DllImport("CRYPT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CertOpenStore(
      int storeProvider,
      int encodingType,
      IntPtr hcryptProv,
      int flags,
      String pvPara
    );

    public const Int32 CRYPTUI_WIZ_IMPORT_SUBJECT_FILE = 1;
    public const Int32 CRYPT_EXPORTABLE = 0x00000001;
    public const Int32 CRYPT_USER_PROTECTED = 0x00000002;
    public const Int32 CRYPTUI_WIZ_NO_UI = 0x0001;

    private static int CERT_STORE_PROV_SYSTEM = 10;
    private static int CERT_SYSTEM_STORE_CURRENT_USER = (1 << 16);
    private static int CERT_SYSTEM_STORE_LOCAL_MACHINE = (2 << 16);

    static void Main(string[] args)
    {
      if (args.Length != 1)
      {
        Console.WriteLine("Usage: certimp.exe list.crl");
        Environment.ExitCode = 1;
      }
      else
      {
        IntPtr hLocalCertStore = CertOpenStore(
          CERT_STORE_PROV_SYSTEM,
          0,
          IntPtr.Zero,
          CERT_SYSTEM_STORE_LOCAL_MACHINE,
          "ROOT"
        );

        CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc = new CRYPTUI_WIZ_IMPORT_SRC_INFO();
        importSrc.dwSize = Marshal.SizeOf(importSrc);
        importSrc.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_FILE;
        importSrc.pwszFileName = args[0];
        importSrc.pwszPassword = null;
        importSrc.dwFlags = CRYPT_EXPORTABLE | CRYPT_USER_PROTECTED;

        if (!CryptUIWizImport(
            CRYPTUI_WIZ_NO_UI,
            IntPtr.Zero,
            IntPtr.Zero,
            ref importSrc,
            hLocalCertStore
          ))
        {
          Console.WriteLine("CryptUIWizImport error " + Marshal.GetLastWin32Error());
          Environment.ExitCode = -1;
        }
      }
    }
  }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Runtime.InteropServices;
命名空间控制台应用程序2
{
班级计划
{
公共结构CRYPTUI_WIZ_IMPORT_SRC_INFO
{
公共Int32 dwSize;
公共主体选择;
[Marshallas(UnmanagedType.LPWStr)]公共字符串pwszFileName;
公共Int32 DWG标志;
[Marshallas(UnmanagedType.LPWStr)]公共字符串密码;
}
[DllImport(“CryptUI.dll”,CharSet=CharSet.Auto,SetLastError=true)]
公共静态外部布尔加密UIWIZIMPORT(
Int32 dwFlags,
IntPtr hwndParent,
IntPtr PWSZ名称,
参考CRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
IntPtr hDestCertStore
);
[DllImport(“CRYPT32.DLL”,CharSet=CharSet.Auto,SetLastError=true)]
公共静态外部IntPtr CertOpenStore(
int storeProvider,
int编码类型,
IntPtr hcryptProv,
int标志,
字符串pvPara
);
public const Int32 CRYPTUI_WIZ_IMPORT_SUBJECT_FILE=1;
public const Int32 CRYPT_EXPORTABLE=0x00000001;
public const Int32 CRYPT\u USER\u PROTECTED=0x00000002;
public const Int32 CRYPTUI_WIZ_NO_UI=0x0001;
专用静态内部证书存储系统=10;

私有静态int证书系统存储当前用户=(1我们只能使用Win32 API来完成这项工作。没有一流的C#系统API来完成这项工作。请参阅

我将CryptUIWizImport函数包装为一个C#控制台应用程序,它对安装证书和CRL非常有吸引力。非常感谢!您有兴趣发布源代码,以帮助下一个人吗?我非常感兴趣在源代码中…因为我有完全相同的问题。certutil不是标准安装的一部分。我相信它只在安装了证书服务时安装(尽管我可能错了).当你说下载是最简单的部分时?你能分享一下你用来实现这一点的技巧吗。Thanks@Raj几乎每个证书颁发机构或签名者都会将CRL位置发布为证书元数据的一部分。打开有问题的证书并查找名为“CRL分发点”的字段。实际上,这是一个一般性的问题,您应该询问,而不只是作为评论。是的,我知道分发点是证书中的一个字段。目前我使用远程对象检索函数,[CryptoAPI]从CDP中检索。我也知道,如果你只是复制URL并在浏览器中通过它们,CRL也会被下载。我请你发表评论的原因是,你提到CRL检索是很容易的部分,所以我假设你有一些实用工具或东西可以为你做这件事。但显然,我的假设是上的错误。感谢您的响应。注意:您还可以创建一个X509Store,打开()并将其StoreHandle属性作为最后一个参数传递给CryptUIWizImport。注意:不管文档怎么说,CRYPTUI_WIZ_NO_UI标志都不会阻止弹出一个询问“是否要替换当前CRL?”的对话框当目标存储区已包含具有相同或更新有效期的CRL时。(在Win2008 R2上测试)注意:要将CRL添加到Windows证书存储区,比(可能)通过UI更直接,可以从crypt32.dll P/调用CertAddCRLContextToStore Win32函数。