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