在其他用户上安装PFX证书

本文关键字:PFX 证书 安装 其他 用户 | 更新日期: 2023-09-27 18:18:12

下面的代码可以完美地在当前用户上安装一个pfx。我想安装它在另一个用户,通过提供用户名和密码(无需与该用户登录)。我之前用批处理文件做了这件事,我怎么能用c#做到这一点?

我尝试了一些东西,包括模仿,但都不能使它工作。

X509Certificate2 certificate = new X509Certificate2("C:''teste''cert.pfx", "password");
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();

更新:

由于Bill的代码,只要用户登录,该过程就可以正常工作。一旦注销,在尝试安装pfx时就会抛出异常。"系统找不到指定的文件"。如果用户重新登录,它又可以工作了!!

这段代码是非常有用的,因为它是,但如果它也可以工作时,用户是离线的,这将是完美的工作!有办法吗?

提前感谢!

// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
    int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
public void DoWorkUnderImpersonation() {
    //elevate privileges before doing file copy to handle domain security
    WindowsImpersonationContext impersonationContext = null;
    IntPtr userHandle = IntPtr.Zero;
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;
    string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
    string user = ConfigurationManager.AppSettings["ImpersonationUser"];
    string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
    try {
        Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
        // if domain name was blank, assume local machine
        if (domain == "")
            domain = System.Environment.MachineName;
        // Call LogonUser to get a token for the user
        bool loggedOn = LogonUser(user,
                                    domain,
                                    password,
                                    LOGON32_LOGON_INTERACTIVE,
                                    LOGON32_PROVIDER_DEFAULT,
                                    ref userHandle);
        if (!loggedOn) {
            Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
            return;
        }
        // Begin impersonating the user
        impersonationContext = WindowsIdentity.Impersonate(userHandle);
        Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
        //run the program with elevated privileges (like file copying from a domain server)
        DoWork();
    } catch (Exception ex) {
        Console.WriteLine("Exception impersonating user: " + ex.Message);
    } finally {
        // Clean up
        if (impersonationContext != null) {
            impersonationContext.Undo();
        }
        if (userHandle != IntPtr.Zero) {
            CloseHandle(userHandle);
        }
    }
}

private void DoWork() {
    //everything in here has elevated privileges
    X509Certificate2 certificate = new X509Certificate2("C:''teste''cert.pfx", "password");
    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
    store.Close();
}

在其他用户上安装PFX证书

你是如何进行模仿的?我以前已经成功地使用了这个答案中的模拟片段:如何正确使用LogonUser从工作组客户端模拟域用户

我使用它的方式是将它封装在DLL中,然后从powershell调用它。它可以用于访问该用户的证书存储,从而允许StoreLocation。

要将此应用到您的情况,您可以尝试:

// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
    int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
public void DoWorkUnderImpersonation() {
    //elevate privileges before doing file copy to handle domain security
    WindowsImpersonationContext impersonationContext = null;
    IntPtr userHandle = IntPtr.Zero;
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;
    string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
    string user = ConfigurationManager.AppSettings["ImpersonationUser"];
    string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
    try {
        Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
        // if domain name was blank, assume local machine
        if (domain == "")
            domain = System.Environment.MachineName;
        // Call LogonUser to get a token for the user
        bool loggedOn = LogonUser(user,
                                    domain,
                                    password,
                                    LOGON32_LOGON_INTERACTIVE,
                                    LOGON32_PROVIDER_DEFAULT,
                                    ref userHandle);
        if (!loggedOn) {
            Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
            return;
        }
        // Begin impersonating the user
        impersonationContext = WindowsIdentity.Impersonate(userHandle);
        Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
        //run the program with elevated privileges (like file copying from a domain server)
        DoWork();
    } catch (Exception ex) {
        Console.WriteLine("Exception impersonating user: " + ex.Message);
    } finally {
        // Clean up
        if (impersonationContext != null) {
            impersonationContext.Undo();
        }
        if (userHandle != IntPtr.Zero) {
            CloseHandle(userHandle);
        }
    }
}

private void DoWork() {
    //everything in here has elevated privileges
    X509Certificate2 certificate = new X509Certificate2("C:''teste''cert.pfx", "password");
    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
    store.Close();
}