创建Windows凭据,直接上代码
备注,这里需要注意一点:如果是xp系统的话需要使用(IP\用户名)作为用户名,而win7和win10则可直接使用(用户名)作为用户名,当然也支持(IP\用户名)作为用户名。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Login
{
public class WindowsCredTools
{
/// <summary>
/// 凭据类型
/// </summary>
public enum CRED_TYPE : uint
{
//普通凭据
GENERIC = 1,
//域密码
DOMAIN_PASSWORD = 2,
//域证书
DOMAIN_CERTIFICATE = 3,
//域可见密码
DOMAIN_VISIBLE_PASSWORD = 4,
//一般证书
GENERIC_CERTIFICATE = 5,
//域扩展
DOMAIN_EXTENDED = 6,
//最大
MAXIMUM = 7,
// Maximum supported cred type
MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes
}
//永久性
public enum CRED_PERSIST : uint
{
SESSION = 1, //本地计算机
LOCAL_MACHINE = 2, //企业
ENTERPRISE = 3,
}
internal class NativeCredMan
{
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
//读取凭据信息
static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
//增加凭据
static extern bool CredWrite([In] ref NativeCredential userCredential, [In] UInt32 flags);
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
static extern bool CredFree([In] IntPtr cred);
[DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
//删除凭据
static extern bool CredDelete(string target, CRED_TYPE type, int flags);
//[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
//static extern bool CredEnumerateold(string filter, int flag, out int count, out IntPtr pCredentials);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CredEnumerate(string filter, uint flag, out uint count, out IntPtr pCredentials);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct NativeCredential
{
public UInt32 Flags;
public CRED_TYPE Type;
public IntPtr TargetName;
public IntPtr Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public IntPtr CredentialBlob;
public UInt32 Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public IntPtr TargetAlias;
public IntPtr UserName;
internal static NativeCredential GetNativeCredential(Credential cred)
{
NativeCredential ncred = new NativeCredential();
ncred.AttributeCount=0;
ncred.AttributeCount=0;
ncred.Attributes = IntPtr.Zero;
ncred.Comment = IntPtr.Zero;
ncred.TargetAlias = IntPtr.Zero;
ncred.Type = cred.Type;
ncred.Persist = (UInt32)cred.Persist;
ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize;
ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName);
ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob);
ncred.UserName = Marshal.StringToCoTaskMemUni(cred.UserName);
// var ncred = new NativeCredential
// {
// AttributeCount = 0,
// Attributes = IntPtr.Zero,
// Comment = IntPtr.Zero,
// TargetAlias = IntPtr.Zero,
// //Type = CRED_TYPE.DOMAIN_PASSWORD,
// Type = cred.Type,
// Persist = (UInt32)cred.Persist,
// CredentialBlobSize = (UInt32)cred.CredentialBlobSize,
// TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName),
// CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob),
// UserName = Marshal.StringToCoTaskMemUni(cred.UserName)
// };
return ncred;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Credential
{
public UInt32 Flags;
public CRED_TYPE Type;
public string TargetName;
public string Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public string CredentialBlob;
public CRED_PERSIST Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public string TargetAlias;
public string UserName;
}
/// <summary>
/// 向添加计算机的凭据管理其中添加凭据
/// </summary>
/// <param name="key">internet地址或者网络地址</param>
/// <param name="userName">用户名</param>
/// <param name="secret">密码</param>
/// <param name="type">密码类型</param>
/// <param name="credPersist"></param>
/// <returns></returns>
public static int WriteCred(string key, string userName, string secret, CRED_TYPE type, CRED_PERSIST credPersist)
{
byte[] byteArray = Encoding.Unicode.GetBytes(secret);
if (byteArray.Length > 512)
throw new ArgumentOutOfRangeException("The secret message has exceeded 512 bytes.");
Credential cred = new Credential();
cred.TargetName = key;
cred.CredentialBlob = secret;
cred.CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length;
cred.AttributeCount = 0;
cred.Attributes = IntPtr.Zero;
cred.UserName = userName;
cred.Comment = null;
cred.TargetAlias = null;
cred.Type = type;
cred.Persist = credPersist;
#region
// var cred = new Credential
// {
// TargetName = key,
// CredentialBlob = secret,
// CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length,
// AttributeCount = 0,
// Attributes = IntPtr.Zero,
// UserName = userName,
// Comment = null,
// TargetAlias = null,
// Type = type,
// Persist = credPersist
// };
#endregion
NativeCredential ncred = NativeCredential.GetNativeCredential(cred);
bool written = CredWrite(ref ncred, 0);
int lastError = Marshal.GetLastWin32Error();
if (written)
{
return 0;
}
string message = "";
if (lastError == 1312)
{
message = (string.Format(String.Format("Failed to save {0} with error code {{0}}.", key), lastError)
+ " This error typically occurrs on home editions of Windows XP and Vista. Verify the version of Windows is Pro/Business or higher.");
}
else
{
message = string.Format(String.Format("Failed to save {0} with error code {{0}}.", key), lastError);
}
return 1;
}
/// <summary>
/// 读取凭据
/// </summary>
/// <param name="targetName"></param>
/// <param name="credType"></param>
/// <param name="reservedFlag"></param>
/// <param name="intPtr"></param>
/// <returns></returns>
public static bool WReadCred(string targetName, CRED_TYPE credType, int reservedFlag, out IntPtr intPtr)
{
return CredRead(targetName, CRED_TYPE.DOMAIN_PASSWORD, reservedFlag, out intPtr);
}
/// <summary>
/// 删除凭据
/// </summary>
/// <param name="target"></param>
/// <param name="type"></param>
/// <param name="flags"></param>
/// <returns></returns>
public static bool DeleteCred(string target, CRED_TYPE type, int flags)
{
return CredDelete(target, type, flags);
}
}
/// <summary>
/// 创建Windows凭据
/// </summary>
/// <param name="key">IP或者网络地址</param>
/// <param name="userName">用户名</param>
/// <param name="password">用户密码</param>
/// <returns></returns>
public static bool CreateCred(string key, string userName, string password)
{
//用于标记凭据添加是否成功 i=0:添加成功;i=1:添加失败
int i = 0;
try
{
i = NativeCredMan.WriteCred(key,
userName,
password,
CRED_TYPE.DOMAIN_PASSWORD,
CRED_PERSIST.LOCAL_MACHINE);
}
catch
{
i = 1;
}
if (i == 0)
return true;
else
return false;
}
/// <summary>
/// 查询凭据是否存在
/// </summary>
/// <param name="targetName">IP或者网络地址</param>
/// <returns>是否存在</returns>
public static bool QueryCred(string targetName)
{
IntPtr intPtr = new IntPtr();
bool flag = false;
try
{
flag = NativeCredMan.WReadCred(targetName, CRED_TYPE.DOMAIN_PASSWORD, 1, out intPtr);
}
catch
{
flag = false;
}
return flag;
}
/// <summary>
/// 删除凭据
/// </summary>
/// <param name="targetName">IP或者网络地址</param>
/// <returns>是否删除成功</returns>
public static bool DeleteCred(string targetName)
{
bool flag = false;
try
{
IntPtr intPtr = new IntPtr();
if (NativeCredMan.WReadCred(targetName, CRED_TYPE.DOMAIN_PASSWORD, 1, out intPtr))
{
flag = NativeCredMan.DeleteCred(targetName.Trim(), CRED_TYPE.DOMAIN_PASSWORD, 0);
}
else
{
flag = true;
}
}
catch
{
flag = false;
}
return flag;
}
}
}