c# - 在不同的用户上安装 PFX 证书

标签 c# ssl-certificate remote-desktop pfx

下面的代码可以完美地在当前用户上安装 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();
}

最佳答案

您是如何开始模仿的?我过去曾成功地使用过这个答案中的模拟片段: How to use LogonUser properly to impersonate domain user from workgroup client

我使用它的方式是将它包装在一个 DLL 中并从 powershell 中调用它。它可能适用于访问该用户的证书存储,从而允许 StoreLocation.CurrentUser 执行它的操作。

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

// 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();
}

关于c# - 在不同的用户上安装 PFX 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33189898/

相关文章:

c# - 如何在运行时知道属于结构体的 char 数组的长度

linux - 私有(private) Docker 注册表错误

linux - SSH端口转发

c - C 语言远程桌面项目

c# - 通过远程桌面连接时出现 IValueConverter NullReferenceException

c# - 由于泛型类型导致不必要的长类名

c# - MVC3 AJAX 中的分页数据

c# - 在 Azure 上运行时的输出与在本地构建上运行时的输出不同

android - 在 Android 中发布和获取的 HttpsURL 连接

ssl - 如何刷新1337端口代理服务器的SSL证书?