Skip to content

Instantly share code, notes, and snippets.

@Nonlinearsound
Last active June 8, 2022 06:24
Show Gist options
  • Save Nonlinearsound/e28d633ecfd86353053c8a981cd4337a to your computer and use it in GitHub Desktop.
Save Nonlinearsound/e28d633ecfd86353053c8a981cd4337a to your computer and use it in GitHub Desktop.

Storing and retreiving Windows Credential Manager info in C# and Go

Lately I had the need for storing SMTP credentials somewhere on the system to be used for a small Go application that would automatically send mails to administrators in case, a certain ETW event would have fired. The solution on Windows is to use the windows Credential Manager. On Linux you could use pass.

I needed both solutions for Go and C#.

Go

In Go it's pretty simple as Daniel Joos already wrote a nice package for exactly that purpose. You can get it here:

github.com/danieljoos/wincred

So we go get the package after initialising our go mod in the folder, we created.

mkdir winpwdmanager
cd winpwdmanager
go mod init someurl.org/winpwdmanager
go get github.com/danieljoos/wincred
New-Item main.go
vscode .

The code for storing and reading our password looks like this:

package main

import (
	"fmt"

	"github.com/danieljoos/wincred"
)

func main() {
	cred := wincred.NewGenericCredential("myGoApplication")
	cred.CredentialBlob = []byte("my secret")
	err := cred.Write()

	if err != nil {
		fmt.Println(err)
	}

	_cred, err := wincred.GetGenericCredential("myGoApplication")
	if err == nil {
		fmt.Println(string(_cred.CredentialBlob))
	}

}

It will output

my secret

C-Sharp

For his we open Visual Studio and create a new console application project for the .Net Framework (I chose 4.7.2 as the minimum) Then we get the Nuget package https://www.nuget.org/packages/CredentialManagement/ After that we get the namespace CredentialManagement tht we can use.´in our code. Here is the complete code for storing and reading a username and password for a selected target.

using CredentialManagement;
using System;

namespace CredentialsTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

            bool success = new Credential
            {
                Target = "csharpcredentialstest",
                Username = "myusername",
                Password = "supersecretpassword",
                PersistanceType = PersistanceType.LocalComputer
            }.Save();

            if (success)
            {
                var cm = new Credential { Target = "csharpcredentialstest" };
                if (!cm.Load())
                {
                    Console.WriteLine("Error in retreiving credentials for csharpcredentialstest}");
                }
                else
                {
                    Console.WriteLine("Username:{0} Password:{1}", cm.Username, cm.Password);
                }
            }

            Console.ReadLine();
        }
    }
}

The application should output the following:

Username:myusername Password:supersecretpassword
@Nonlinearsound
Copy link
Author

Nonlinearsound commented Mar 22, 2022

There also seems to be a Powershell module available but I didn't have the time yet to test it.
Grab it here; https://www.powershellgallery.com/packages/CredentialManager/2.0

@Nonlinearsound
Copy link
Author

Also, a very nice discussion of the topic on stackoverflow, this time about how to do it in C++ using the Win32 API.
https://stackoverflow.com/questions/9221245/how-do-i-store-and-retrieve-credentials-from-the-windows-vault-credential-manage

@Nonlinearsound
Copy link
Author

Nonlinearsound commented Jun 8, 2022

In Powershell, the Credential Manager can be accessed by using this method:

https://sites.utexas.edu/glenmark/2019/10/21/using-passwordvault-with-powershell/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment