I have a requirement to programmatically save a username and password on the local workstation and retrieve them back.

What would be the most secure way of doing this?

I have used DPAPI in the past with success but it looks like DPAPI uses 3des which has been deprecated.

Would CNG-DPAPI be the better choice? Any other methods that would be more secure?

Thanks, Mike

  • You married to Windows?
    – hft
    Sep 7, 2018 at 22:15
  • Yes I am...The application is running on windows.
    – Mike M
    Sep 10, 2018 at 13:01
  • Okay, why are you saving/reusing the password (I'm assuming you're using the password for something)? Is it possible, if you're on Windows, to just use the logged in user's domain id? Also, recent versions of Windows provides a Credential Manager that can be used to save/access passwords (this is what git, and your browser, will use) - is that an option? Nov 12, 2018 at 18:17
  • The password is being used by a server (not the service account) to access a switch. The reason it needs to be saved and can't be typed in is in case the station is rebooted. The service needs to start and access the switch without user input. I haven't checked into Credential Manager yet, is that usable by a service?
    – Mike M
    Nov 14, 2018 at 15:47

1 Answer 1


3DES has not been deprecated, nor has DPAPI. While the 3DES algorithm is not ideal and should not be used in new designs where avoidable, the best attack we know against is is a meet-in-the-middle attack which requires 512PiB of error-correcting RAM and 2112 + 256 operations. Considering other possible attacks against DPAPI, e.g. using the mimikatz DPAPI module on a running system, this seems rather outlandish.

CNG-DPAPI (which is called DPAPI-NG now) would be a better choice for modern designs. Unfortunately the examples out there are fairly scant, leaving you to work a lot of things out on your own. The following is a high-level example of how you might implement secret storage using DPAPI-NG:

  • Call NCryptCreateProtectionDescriptor with dwFlags set to 0 and pwszDescriptorString set to a protection descriptor string. To protect the data such that only the current user can access it, use "LOCAL=user", and for machine-wide protection use "LOCAL=machine". You can also encrypt to a set of web credentials under an ASP context, a certificate from the certificate store, a domain user by specifying a SID, or you can specify a fully custom security descriptor using SSDL.
  • Call NCryptProtectSecret, passing in the handle you got from the above operation, in order to encrypt small amounts of data (e.g. a credential string)
  • Call NCryptStreamOpenToProtect if you want to encrypt a lot of data. This opens up a stream that you can write data into via NCryptStreamUpdate.
  • Call NCryptUnprotectSecret in order to decrypt data that was encrypted with NCryptProtectSecret.
  • Call NCryptStreamOpenToUnprotect to decrypt data that was encrypted with NCryptStreamOpenToProtect. Again, NCryptStreamUpdate is used here.
  • If you used any of the stream functions, call NCryptStreamClose to close them.
  • Call NCryptCloseProtectionDescriptor to close the protection descriptor handle you created in the first step.

DPAPI-NG is still affected by tools such as mimikatz, but that's just an inherent part of how operating system security works - if an attacker is running code as an administrator, they have won.

The old API for DPAPI is much simpler, but the new API has more comprehensive support for different security scenarios as described above. The cryptography in use is certainly not the weakest link in the chain for either API.

  • You're right, 3DES is not quite deprecated yet, but the latest draft revision of SP 800-131A from NIST does deprecate the algorithm through 2023 in table 1. Nov 12, 2018 at 16:14
  • 1
    @JesseDanielMitchell I'm aware of the new NIST recommendations, but as long as you're not working for the government or building software for them you're not strictly beholden to those requirements. The main reason to deprecate 3DES right now is that it's really slow by comparison to AES, especially on modern processors with AES instruction extensions. In the context of building a cryptographic protocol, I'd absolutely reject the use of 3DES, but in this specific context the underlying cipher is not of any major concern.
    – Polynomial
    Nov 12, 2018 at 16:54
  • Thank you for such a detailed explanation, it really helps. One question does DPAPI NG support the newer encryption methods like AES 256, SHA2?
    – Mike M
    Nov 14, 2018 at 15:54
  • @MikeM DPAPI-NG is built on AES and RSA; I am unsure as to the hash function in use but would make an educated guess that it is SHA2 since CNG does include a SHA2 implementation.
    – Polynomial
    Nov 14, 2018 at 17:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .