设为首页 收藏本站
查看: 525|回复: 0

[经验分享] C#代码实现对Windows凭据的管理

[复制链接]

尚未签到

发表于 2018-6-19 12:17:41 | 显示全部楼层 |阅读模式
  
private void button1_Click(object sender, EventArgs e)         {
  //ip地址或者网络路径 例如:TERMSRV/192.168.2.222
  string key = txtIP.Text.Trim();
  string userName = txtUserName.Text.Trim();
  string password = txtPassword.Text.Trim();
  //用于标记凭据添加是否成功 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)
  txtMsg.Text = "添加成功";
  else
  txtMsg.Text = "添加失败";
  
}
  
/// <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)
  
        {
  
            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)
  
    {
  
        var byteArray = Encoding.Unicode.GetBytes(secret);
  
        if (byteArray.Length > 512)
  
            throw new ArgumentOutOfRangeException("The secret message has exceeded 512 bytes.");
  
        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
  
       };
  
       var ncred = NativeCredential.GetNativeCredential(cred);
  
       var written = CredWrite(ref ncred, 0);
  
       var lastError = Marshal.GetLastWin32Error();
  
       if (written)
  
       {
  
           return 0;
  
       }
  

  
       var message = "";
  
       if (lastError == 1312)
  
       {
  
           message = (string.Format("Failed to save " + key + " with error code {0}.", 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("Failed to save " + key + " with error code {0}.", lastError);
  
       }
  
       MessageBox.Show(message);
  
       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>
  
/// 查询凭据是否存在
  
/// </summary>
  
/// <param name="sender"></param>
  
/// <param name="e"></param>
  
private void btnQuery_Click(object sender, EventArgs e)
  
{
  
    string targetName = txtIP.Text.Trim();
  
    IntPtr intPtr=new IntPtr ();
  
    bool flag = false;
  
    try
  
    {
  
        flag = NativeCredMan.WReadCred(targetName, CRED_TYPE.DOMAIN_PASSWORD, 1, out intPtr);
  
    }
  
    catch{
  
        flag = false;
  
    }
  

  
    if (flag)
  
        txtMsg.Text = "该凭据已存在";
  
    else
  
        txtMsg.Text = "该凭据目前不存在";
  
}
  

  
private void btnDelete_Click(object sender, EventArgs e)
  
{
  
    string targetName = txtIP.Text.Trim();
  
    bool flag = false;
  
    try
  
    {
  
        flag = NativeCredMan.DeleteCred(targetName, CRED_TYPE.DOMAIN_PASSWORD,0);
  
    }
  
    catch
  
    {
  
        flag = false;
  
    }
  

  
    if (flag)
  
        txtMsg.Text = "该凭据已删除";
  
    else
  
        txtMsg.Text = "删除失败";
  
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-525851-1-1.html 上篇帖子: MS16-072导致WINDOWS 2008 2012基于用户过滤的组策略大面积失效 下篇帖子: windows下安装feedparser-12149803
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表