使用C#从Windows凭据存储中检索凭据

Kir*_*chi 33 c# credentials

我只想查询凭据存储(或Win8中调用的Vault)并获取登录数据.在这种情况下,MSDN真的没有用,我也不想要任何C++ pInvoke方法.

我知道这里曾经问过几次类似的问题,但这些解决方案都不适合我的情况.我没有使用Metro App编程,因此PasswordVault(看起来)不可用.我只是创建一个简单的C#WPF桌面应用程序.

理想情况下,它应该适用于多个Windows版本,但首选Win8.

更具体地说,我想查询来自CRM插件的存储数据,以便自动让我的应用程序登录到CRM服务器,而无需用户请求他的凭据.这意味着,如果这是可能的......

那么如何访问Windows凭据存储?

小智 46

有一个我一直在使用的Nuget图书馆,名为CredentialManagement http://nuget.org/packages/CredentialManagement/

用法非常简单.我把它包裹了一点,但可能不需要:

public static class CredentialUtil
{
    public static UserPass GetCredential(string target)
    {
        var cm = new Credential {Target = target};
        if (!cm.Load())
        {
            return null;
        }

        // UserPass is just a class with two string properties for user and pass
        return new UserPass(cm.Username, cm.Password);
    }

    public static bool SetCredentials(
         string target, string username, string password, PersistanceType persistenceType)
    {
       return new Credential {Target = target,
                              Username = username,
                              Password = password,
                              PersistanceType =  persistenceType}.Save();
    }

    public static bool RemoveCredentials(string target)
    {
        return new Credential { Target = target }.Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)

样品用法:

CredentialUtil.SetCredentials("FOO", "john", "1234", PersistanceType.LocalComputer);
var userpass = CredentialUtil.GetCredential("FOO");
Console.WriteLine($"User: {userpass.Username} Password: {userpass.Password}");
CredentialUtil.RemoveCredentials("FOO");
Debug.Assert(CredentialUtil.GetCredential("FOO") == null);
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣自己实现它,请浏览源代码:http: //credentialmanagement.codeplex.com/SourceControl/latest

诀窍是Credential Manager中没有C#API.这个库很好地包装了其他.dll入口点.:-)

  • 这个答案有两个注意事项,它们不一定是库的缺陷,而是Windows中凭证管理器的缺陷.您基本上可以使用此加载和解密计算机上任何凭据的用户名和密码,任何其他应用程序也可以.任何意义上的说法都不安全或不安全.另外,当然还有其他用户提到的纯文本字符串的使用.但是,单独的第一点应该让你对整个系统持怀疑态度. (3认同)
  • 害怕!我可以执行CredentialManager.GetCredentials(“ outlook.office365.com”); 并以明文形式获取我的用户名/密码! (3认同)