Retrieve credentials from Windows Credentials Store using C#
There is a NuGet library that I've been using, called CredentialManagement.
The usage is pretty simple. I wrapped it a little, but I probably didn't need to:
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();
}
}
Sample usage:
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);
If you're interested in implementing it yourself, browse the source:
http://credentialmanagement.codeplex.com/SourceControl/latest
The trick is that there is no C# API into the Credential Manager. This library wraps the other .dll entry points nicely. :-)
How to store and retrieve credentials on Windows using C#
You can use the Windows Credential Management API. This way you will ask the user for the password only once and then store the password in Windows Credentials Manager.
Next time your application starts and it needs to use the password it will read it from Windows Credentials Manager. One can use the Windows Credential Management API directly using P/Invoke (credwrite, CredRead, example here) or via a C# wrapper CredentialManagement.
Sample usage using the NuGet CredentialManagement package:
public class PasswordRepository
{
private const string PasswordName = "ServerPassword";
public void SavePassword(string password)
{
using (var cred = new Credential())
{
cred.Password = password;
cred.Target = PasswordName;
cred.Type = CredentialType.Generic;
cred.PersistanceType = PersistanceType.LocalComputer;
cred.Save();
}
}
public string GetPassword()
{
using (var cred = new Credential())
{
cred.Target = PasswordName;
cred.Load();
return cred.Password;
}
}
}
I don't recommend storing passwords in files on client machines. Even if you encrypt the password, you will probably embed the decryption key in the application code which is not a good idea.
.NET Core: How to access Windows Credential Manager if running on Windows (otherwise ignore)?
I ended up using the Data Protection API for Windows (DPAPI) to store secrets in a file that is encrypted within the scope of the logged in user.
Encrypted storage of a password:
try
{
var passwordBytes = Encoding.UTF8.GetBytes(password);
var protectedPasswordBytes = ProtectedData.Protect(passwordBytes, null, DataProtectionScope.CurrentUser);
var protectedPasswordBytesBase64 = Convert.ToBase64String(protectedPasswordBytes);
File.WriteAllText(passwordFilePath, protectedPasswordBytesBase64);
} catch (PlatformNotSupportedException)
{
Debug.WriteLine("Could not store credentials");
}
Decryption:
if (File.Exists(passwordFilePath))
{
var protectedPasswordBytesBase64 = File.ReadAllText(passwordFilePath);
var protectedPasswordBytes = Convert.FromBase64String(protectedPasswordBytesBase64);
var passwordBytes = ProtectedData.Unprotect(protectedPasswordBytes, null, DataProtectionScope.CurrentUser);
password = Encoding.UTF8.GetString(passwordBytes);
}
(Only works on Windows, for other OSes I'll use other solutions.)
Access Windows Credentials in Credential Manager
There is a Nuget library called CredentialManagement http://nuget.org/packages/CredentialManagement/
from the answer here: Retrieve Credentials from Windows Credentials Store using C#
works perfectly
var cm = new Credential();
cm.Target = "mycredentialname";
if (!cm.Exists())
{
Console.WriteLine("cm is null");
}
cm.Load();
Console.WriteLine("Password: " + cm.Password);
Console.WriteLine("Username: " + cm.Username);
Retrieve Credentials from Windows generic Credentials Store using C# in ASP.net website under IIS
You should switch "Load User Profile" parameter of IIS App Pool to true. Then your code should start working.
Related Topics
Linq to Entities Only Supports Casting Edm Primitive or Enumeration Types with Ientity Interface
Icecast 2: Protocol Description, Streaming to It Using C#
How to Render a Razor View to a String in ASP.NET MVC 3
How to Find the Difference Between Two Images
Could Not Load File or Assembly ... the Parameter Is Incorrect
What Is the Correct Performance Counter to Get CPU and Memory Usage of a Process
What's the New C# Await Feature Do
How to Remove All White Space from the Beginning or End of a String
How to Access Internal Class Using Reflection
Is There Anything Like Asynchronous Blockingcollection<T>
Visual Studio Debugging "Quick Watch" Tool and Lambda Expressions
Removing Nodes from an Xmldocument