Securely Store a Password in the Application in C#

How to securely save username/password (local)?

If you are just going to verify/validate the entered user name and password, use the Rfc2898DerivedBytes class (also known as Password Based Key Derivation Function 2 or PBKDF2). This is more secure than using encryption like Triple DES or AES because there is no practical way to go from the result of RFC2898DerivedBytes back to the password. You can only go from a password to the result. See Is it ok to use SHA1 hash of password as a salt when deriving encryption key and IV from password string? for an example and discussion for .Net or String encrypt / decrypt with password c# Metro Style for WinRT/Metro.

If you are storing the password for reuse, such as supplying it to a third party, use the Windows Data Protection API (DPAPI). This uses operating system generated and protected keys and the Triple DES encryption algorithm to encrypt and decrypt information. This means your application does not have to worry about generating and protecting the encryption keys, a major concern when using cryptography.

In C#, use the System.Security.Cryptography.ProtectedData class. For example, to encrypt a piece of data, use ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes().
byte[] plaintext;

// Generate additional entropy (will be used as the Initialization vector)
byte[] entropy = new byte[20];
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(entropy);
}

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy,
DataProtectionScope.CurrentUser);

Store the entropy and ciphertext securely, such as in a file or registry key with permissions set so only the current user can read it. To get access to the original data, use ProtectedData.Unprotect():

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy,
DataProtectionScope.CurrentUser);

Note that there are additional security considerations. For example, avoid storing secrets like passwords as a string. Strings are immutable, being they cannot be notified in memory so someone looking at the application's memory or a memory dump may see the password. Use SecureString or a byte[] instead and remember to dispose or zero them as soon as the password is no longer needed.

Securely store a password in the application in C#

You can use the built-in SecureString, it stores the underlying information encrypted in the memory. If you use WPF there is a control PasswordBox which also stores the password in a SecureString.

C# - Securely storing a password locally

The standard method for storing a password in a configuration file is to use a strong hash algorithm. Read the answer at How to store passwords in Winforms application? and maybe the wiki article at https://en.wikipedia.org/wiki/Cryptographic_hash_function

How to store username and password securely in .NET Core console app?

You might want to take a look at the ProtectedData class. This encrypts the data to make it inaccessible for all but the current user.

Keep in mind that protecting data from the user himself, especially if the user is an administrator, will rarely be truly secure if the user is skilled.

Store passwords securely in Windows

Use Data Protection API (DPAPI)

  • CryptProtectData to store the data
  • CryptUnprotectData to retrieve the data

Data is protected by the user account credentials, so it can be retrieved by other application running under same account. Alternatively you can use the machine credentials to give access to services.

See Example C Program: Using CryptProtectData for an example.

DPAPI is used by the vast majority of applications to store passwords.

Securely Storing Password in app.config - information overload

Thanks to all, particularl @Cleptus, whose advice I took, for your advice. In the end, I have taken the API key and encrypted it using DPAP security. This key is essentially the access to the API, so now that is secured I have made a separate user to run the windows service, with access to the database using integrated security.

I now have a long, encrypted value in the app.config file for the api key and the password for the windows service is saved using windows security.

Securely store a password in program code?

There is no point in symmetrically encrypting with a string that's hard-coded into your executable. It will only give a false sense of security. No amount of hashing fixes this scheme.

See this Pidgin FAQ for the same point in a different context.

I am unclear why you think you need the inter-app communication to be encrypted. If this communication is local to the machine, then I don't see the need for encryption, particularly encryption that isn't user-specific. Is this a DRM scheme?

EDIT: If it's being passed to a different machine, perhaps you can hard-code a public key, and then have the other machine decrypt with the matching private key.

C# How to store password in application

In fact you'd better not use passwords. If the service runs under the right credentials, you can use that one by using the DefaultNetworkCredentials:

So in your sample:

client.Credentials = CredentialCache.DefaultNetworkCredentials;

This will get you the credentials of the current network user, like DOMAIN\USER.

How can I safely store a password in source code?

Ideally you should not be storing the password in your source code which runs on client machine.

For this type of scenario, still you can avoid hard coding by retrieving the password from server using some API calls after performing the required authentication/ authorization.

If you store the password in the code running on the client side, whatever you do like obfuscation/ encryption/ encoding, it can still be extracted using reverse engineering.

Edit:

Thick client - all logic is on client side. No hosting server. It
would be exaggerated to rent a server just for protecting my email
password. Is there really no other solution? How is connection string
to database then secured in other applications against reverse
engineering?

As mentioned above you can't completely secure it, but you can make it tough to break, for that you can try following steps.

  1. Encrypt your password.
  2. Store the encryption key in multiple parts in different location,
    like one part in code file, one part in configuration file and one
    part in user registry.
  3. Obfuscate your code.


Related Topics



Leave a reply



Submit