2021-06-22

代码 代码 915 人阅读 | 0 人回复

<
C# 验证账号暗码的方法类

前言

日常C#开发过程中朋友们大概会遇到需要验证账号暗码的操纵,本人通过多次验证(踩坑无数),终于找到了一个还算数比较靠谱的方法,现在总结分享给大家,大神们如果有更好的方法请在复兴区告诉我哦! 话不多说 直接上代码

2.类

验证账号类:
  1.   [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
  2.             //读取凭据信息
  3.             static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);
  4.             [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
  5.             //增加凭据
  6.             static extern bool CredWrite([In] ref NativeCredential userCredential, [In] UInt32 flags);
  7.             [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
  8.             static extern bool CredFree([In] IntPtr cred);
  9.             [DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
  10.             //删除凭据
  11.             static extern bool CredDelete(string target, CRED_TYPE type, int flags);
  12.             [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  13.             public static extern bool CredEnumerate(string filter, uint flag, out uint count, out IntPtr pCredentials);
  14.             //登陆验证
  15.             [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  16.             static extern bool LogonUser(string username, string domain,
  17.                                           string password, LogonType logonType,
  18.                                           LogonProvider logonProvider,
  19.                                           out IntPtr userToken);
  20.             [DllImport("Advapi32.DLL")]
  21.             static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
复制代码
3.注意事项

Interactive =2 本地交互登录。最常见的登录方式。
Network=3网络登录 - 最常见的是访问网络共享文件夹或打印机。IIS的认证也是Type 3
Batch=4 筹划任务
Service=5 服务
某些服务是用一个域帐号来运行的,出现Failure常见的情况是管理员更改了域帐号暗码,但是忘记重设Service中的帐号暗码。
Unlock=7 排除屏幕锁定
许多公司都有这样的安全设置:当用户离开屏幕一段时间后,屏保程序会锁定计算机屏幕。解开屏幕锁定需要键入用户名和暗码。此时产生的日志类型就是Type 7
NetworkCleartext=8 网络明文登录 – 通常发生在IIS 的 ASP登录。不推荐
NewCredentials=9 新身份登录 – 通常发生在RunAS方式运行某程序时的登录验证。
RemoteInteractive=10 远程登录 – 比如Terminal service或者RDP方式。但是Windows 2000是没有Type10的,用Type 2。WindowsXP/2003起有Type 10
CachedInteractive=11 缓存登录:

  1. public static class WindowsCredTools
  2.     {
  3.         /// <summary>         
  4.         /// 凭据类型         
  5.         /// </summary>
  6.         public enum CRED_TYPE : uint
  7.         {
  8.             //普通凭据
  9.             GENERIC = 1,
  10.             //域密码
  11.             DOMAIN_PASSWORD = 2,
  12.             //域证书
  13.             DOMAIN_CERTIFICATE = 3,
  14.             //域可见密码
  15.             DOMAIN_VISIBLE_PASSWORD = 4,
  16.             //一般证书
  17.             GENERIC_CERTIFICATE = 5,
  18.             //域扩展
  19.             DOMAIN_EXTENDED = 6,
  20.             //最大
  21.             MAXIMUM = 7,
  22.             // Maximum supported cred type
  23.             MAXIMUM_EX = (MAXIMUM + 1000),  // Allow new applications to run on old OSes
  24.         }
  25.         //永久性
  26.         public enum CRED_PERSIST : uint
  27.         {
  28.             SESSION = 1,             //本地计算机
  29.             LOCAL_MACHINE = 2,             //企业
  30.             ENTERPRISE = 3,
  31.         }
  32.         public enum LogonType : int
  33.         {
  34.             Interactive = 2,
  35.             Network = 3,
  36.             Batch = 4,
  37.             Service = 5,
  38.             Unlock = 7,
  39.             NetworkCleartText = 8,
  40.             NewCredentials = 9,
  41.         }
  42.         public enum LogonProvider : int
  43.         {
  44.             Default = 0,
  45.         }
  46.         internal class NativeCredMan
  47.         {
  48.             [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
  49.             //读取凭据信息
  50.             static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);
  51.             [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
  52.             //增加凭据
  53.             static extern bool CredWrite([In] ref NativeCredential userCredential, [In] UInt32 flags);
  54.             [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
  55.             static extern bool CredFree([In] IntPtr cred);
  56.             [DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
  57.             //删除凭据
  58.             static extern bool CredDelete(string target, CRED_TYPE type, int flags);
  59.             [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  60.             public static extern bool CredEnumerate(string filter, uint flag, out uint count, out IntPtr pCredentials);
  61.             //登陆验证
  62.             [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  63.             static extern bool LogonUser(string username, string domain,
  64.                                           string password, LogonType logonType,
  65.                                           LogonProvider logonProvider,
  66.                                           out IntPtr userToken);
  67.             [DllImport("Advapi32.DLL")]
  68.             static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
  69.             [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  70.             private struct NativeCredential
  71.             {
  72.                 public UInt32 Flags;
  73.                 public CRED_TYPE Type;
  74.                 public IntPtr TargetName;
  75.                 public IntPtr Comment;
  76.                 public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
  77.                 public UInt32 CredentialBlobSize;
  78.                 public IntPtr CredentialBlob;
  79.                 public UInt32 Persist;
  80.                 public UInt32 AttributeCount;
  81.                 public IntPtr Attributes;
  82.                 public IntPtr TargetAlias;
  83.                 public IntPtr UserName;
  84.                 internal static NativeCredential GetNativeCredential(Credential cred)
  85.                 {
  86.                     NativeCredential ncred = new NativeCredential();
  87.                     ncred.AttributeCount = 0;
  88.                     ncred.AttributeCount = 0;
  89.                     ncred.Attributes = IntPtr.Zero;
  90.                     ncred.Comment = IntPtr.Zero;
  91.                     ncred.TargetAlias = IntPtr.Zero;
  92.                     ncred.Type = cred.Type;
  93.                     ncred.Persist = (UInt32)cred.Persist;
  94.                     ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize;
  95.                     ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName);
  96.                     ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob);
  97.                     ncred.UserName = Marshal.StringToCoTaskMemUni(cred.UserName);
  98.                     return ncred;
  99.                 }
  100.             }
  101.             [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  102.             public struct Credential
  103.             {
  104.                 public UInt32 Flags;
  105.                 public CRED_TYPE Type;
  106.                 public string TargetName;
  107.                 public string Comment;
  108.                 public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
  109.                 public UInt32 CredentialBlobSize;
  110.                 public string CredentialBlob;
  111.                 public CRED_PERSIST Persist;
  112.                 public UInt32 AttributeCount;
  113.                 public IntPtr Attributes;
  114.                 public string TargetAlias;
  115.                 public string UserName;
  116.             }
  117.             /// <summary>
  118.             /// 向添加计算机的凭据管理其中添加凭据            
  119.             /// </summary>
  120.             /// <param name="key">internet地址或者网络地址</param>            
  121.             /// <param name="userName">用户名</param>            
  122.             /// <param name="secret">密码</param>            
  123.             /// <param name="type">密码类型</param>            
  124.             /// <param name="credPersist"></param>            
  125.             /// <returns></returns>
  126.             public static int WriteCred(string key, string userName, string secret, CRED_TYPE type, CRED_PERSIST credPersist)
  127.             {
  128.                 byte[] byteArray = Encoding.Unicode.GetBytes(secret);
  129.                 if (byteArray.Length > 512)
  130.                     throw new ArgumentOutOfRangeException("The secret message has exceeded 512 bytes.");
  131.                 Credential cred = new Credential();
  132.                 cred.TargetName = key;
  133.                 cred.CredentialBlob = secret;
  134.                 cred.CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length;
  135.                 cred.AttributeCount = 0;
  136.                 cred.Attributes = IntPtr.Zero;
  137.                 cred.UserName = userName;
  138.                 cred.Comment = null;
  139.                 cred.TargetAlias = null;
  140.                 cred.Type = type;
  141.                 cred.Persist = credPersist;
  142.                 NativeCredential ncred = NativeCredential.GetNativeCredential(cred);
  143.                 bool written = CredWrite(ref ncred, 0);
  144.                 int lastError = Marshal.GetLastWin32Error();
  145.                 if (written)
  146.                 {
  147.                     return 0;
  148.                 }
  149.                 string message = string.Empty;
  150.                 if (lastError == 1312)
  151.                 {
  152.                     message = (string.Format(String.Format("Failed to save {0} with error code {{0}}.", key), lastError)
  153.                     + "  This error typically occurrs on home editions of Windows XP and Vista.  Verify the version of Windows is Pro/Business or higher.");
  154.                 }
  155.                 else
  156.                 {
  157.                     message = string.Format(String.Format("Failed to save {0} with error code {{0}}.", key), lastError);
  158.                 }
  159.                 return 1;
  160.             }
  161.             /// <summary>            
  162.             /// 读取凭据            
  163.             /// </summary>
  164.             /// <param name="targetName"></param>            
  165.             /// <param name="credType"></param>            
  166.             /// <param name="reservedFlag"></param>
  167.             /// <param name="intPtr"></param>            
  168.             /// <returns></returns>
  169.             public static bool WReadCred(string targetName, CRED_TYPE credType, int reservedFlag, out IntPtr intPtr)
  170.             {
  171.                 bool flag = CredRead(targetName, CRED_TYPE.DOMAIN_PASSWORD, reservedFlag, out intPtr);
  172.                 return flag;
  173.             }
  174.             /// <summary>            
  175.             /// 删除凭据            
  176.             /// </summary>
  177.             /// <param name="target"></param>            
  178.             /// <param name="type"></param>            
  179.             /// <param name="flags"></param>            
  180.             /// <returns></returns>
  181.             public static bool DeleteCred(string target, CRED_TYPE type, int flags)
  182.             {
  183.                 return CredDelete(target, type, flags);
  184.             }
  185.             /// <summary>
  186.             /// 登陆测试
  187.             /// </summary>
  188.             /// <param name="username"></param>
  189.             /// <param name="domain"></param>
  190.             /// <param name="password"></param>
  191.             /// <returns></returns>
  192.             public static bool LongonCheck(string username, string domain, string password)
  193.             {
  194.                 IntPtr userToken = IntPtr.Zero;
  195.                 bool bImpersonated = LogonUser(username, domain, password, LogonType.NewCredentials, LogonProvider.Default, out userToken);
  196.                 try
  197.                 {
  198.                     if (bImpersonated)
  199.                     {
  200.                         if (!ImpersonateLoggedOnUser(userToken))
  201.                         {
  202.                             int nErrorCode = Marshal.GetLastWin32Error();
  203.                             CLRLogger.GetInstance().LogDevError("ImpersonateLoggedOnUser error;Code=" + nErrorCode);
  204.                             bImpersonated = false;
  205.                         }
  206.                     }
  207.                 }
  208.                 catch (Exception ex)
  209.                 {
  210.                     bImpersonated = false;
  211.                     CLRLogger.GetInstance().LogDevError("LongonCheck catch ex is " + ex.ToString());
  212.                 }
  213.                 return bImpersonated;
  214.             }
  215.         }
  216.         /// <summary>
  217.         /// 创建Windows凭据
  218.         /// </summary>
  219.         /// <param name="key">IP或者网络地址</param>
  220.         /// <param name="userName">用户名</param>
  221.         /// <param name="password">用户密码</param>
  222.         /// <returns></returns>
  223.         public static bool CreateCred(string key, string userName, string password)
  224.         {
  225.             //用于标记凭据添加是否成功 i=0:添加成功;i=1:添加失败            
  226.             int i = 0;
  227.             try
  228.             {
  229.                 i = NativeCredMan.WriteCred(key,
  230.                 userName,
  231.                 password,
  232.                 CRED_TYPE.DOMAIN_PASSWORD,
  233.                 CRED_PERSIST.LOCAL_MACHINE);
  234.             }
  235.             catch (Exception ex)
  236.             {
  237.                 i = 1;
  238.                 CLRLogger.GetInstance().LogDevError("CreateCred has error : " + ex.Message);
  239.             }
  240.             return i == 0;
  241.         }
  242.         /// <summary>
  243.         /// 查询凭据是否存在         
  244.         /// </summary>
  245.         /// <param name="targetName">IP或者网络地址</param>   
  246.         /// <returns>是否存在</returns>
  247.         public static bool QueryCred(string targetName)
  248.         {
  249.             IntPtr intPtr = new IntPtr();
  250.             bool flag = false;
  251.             try
  252.             {
  253.                 flag = NativeCredMan.WReadCred(targetName, CRED_TYPE.DOMAIN_PASSWORD, 1, out intPtr);
  254.             }
  255.             catch (Exception ex)
  256.             {
  257.                 flag = false;
  258.                 CLRLogger.GetInstance().LogDevError("QueryCred has error : " + ex.Message);
  259.             }
  260.             return flag;
  261.         }
  262.         /// <summary>
  263.         /// 删除凭据
  264.         /// </summary>
  265.         /// <param name="targetName">IP或者网络地址</param>
  266.         /// <returns>是否删除成功</returns>
  267.         public static bool DeleteCred(string targetName)
  268.         {
  269.             bool flag = false;
  270.             try
  271.             {
  272.                 IntPtr intPtr = new IntPtr();
  273.                 if (NativeCredMan.WReadCred(targetName, CRED_TYPE.DOMAIN_PASSWORD, 1, out intPtr))
  274.                 {
  275.                     flag = NativeCredMan.DeleteCred(targetName.Trim(), CRED_TYPE.DOMAIN_PASSWORD, 0);
  276.                 }
  277.                 else
  278.                 {
  279.                     flag = true;
  280.                 }
  281.             }
  282.             catch (Exception ex)
  283.             {
  284.                 flag = false;
  285.                 CLRLogger.GetInstance().LogDevError("DeleteCred has error : " + ex.Message);
  286.             }
  287.             return flag;
  288.         }
  289.         /// <summary>
  290.         /// 登陆验证方法 IP为输出目录的地址,userName为账户名,domain为域名(united-imaging.com),password为密码
  291.         /// </summary>
  292.         /// <param name="username"></param>
  293.         /// <param name="domain"></param>
  294.         /// <param name="password"></param>
  295.         /// <returns></returns>
  296.         public static bool LogonUser(string ip, string username, string domain, string password)
  297.         {
  298.             bool loggedOn = false;
  299.             try
  300.             {
  301.                 if (NativeCredMan.LongonCheck(username, domain, password) && Directory.Exists(ip))
  302.                 {
  303.                     loggedOn = true;
  304.                 }
  305.             }
  306.             catch (Exception ex)
  307.             {
  308.                 loggedOn = false;
  309.                 CLRLogger.GetInstance().LogDevError("LogonUser has error : " + ex.Message);
  310.             }
  311.             return loggedOn;
  312.         }
  313.     }  
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,按照目前互联网开放的原则,我们将在不通知作者的情况下,转载文章;如果原文明确注明“禁止转载”,我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话,请您发送邮箱:Cdnjson@163.com提供相关证明,我们将积极配合您!
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。
回复 关闭延时

使用道具 举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则