Which Encryption algorithm does ProtectedData use? - c#

For password encryption I want to use ProtectedData.
As far as I found out, this is a wrapper for CryptProtectData.
The MSDN only states something vague about encryption based on user credentials
and that decryption usually must be done on the same machine, if user has
no roaming profile.
Which encryption algorithm does it use?
Is there any analysis that states whether this encryption is suiting for password storage?
How else to implement a local password storage?

This MSDN article has more information about CryptProtectData and DPAPI, and should contain the information you need. In particular:
DPAPI initially generates a strong key called a MasterKey, which is
protected by the user's password. DPAPI uses a standard cryptographic
process called Password-Based Key Derivation, described in PKCS #5, to
generate a key from the password. This password-derived key is then
used with Triple-DES to encrypt the MasterKey, which is finally stored
in the user's profile directory.
The article applies to an older version of Windows, so depending on your Windows version, these algorithms might change, but they are probably not going to be less secure than the ones mentioned here.
Whether or not this is suitable for "password storage", depends a bit on what exactly you mean by this and what passwords you're storing I would say.

Related

Where should we be storing the MD5 hashkey for our .Net applications?

We have several Net applications (Winforms and Asp.Net) and use .Net MD5Encryption to encrypt/decrypt user login information. We are using a GUID as the hashkey and store that key in the source of the application. Is this a security vulnerability to do so? Is there a better practice for handling this?
Consider this similar to publishing the hashing details in your documentation. Keeping the details of how you hash passwords secret is at-best defense-in-depth, at worst security-though-obscurity.
A bad actor can't attack any passwords you've hashed unless they also have access to your stored hashes.

How to encrypt stored information, using C#?

I am creating an application which stores multiple passwords of a user. First user has to provide his/her user-name plus password, and after successful login he'll be given all his saved passwords.
I am using md5 encryption method. I've successfully integrated md5 in my log-in module. But the problem is, how can I encrypt the stored passwords (in a file), as there is no legal way to decrypt md5 hash. Please suggest an algo.
Any help would be greatly appreciated!
You would want to use a symmetric encryption algorithm like AES, or 3DES. MD5 is not encryption, it's hashing, and the original password is not actually preserved.
You could use AES Algorithm
Following article may help you to get started:
Keep Your Data Secure with the New Advanced Encryption Standard
The Advanced Encryption Standard (AES) is a National Institute of
Standards and Technology specification for the encryption of
electronic data. It is expected to become the accepted means of
encrypting digital information, including financial,
telecommunications, and government data. This article presents an
overview of AES and explains the algorithms it uses. Included is a
complete C# implementation and examples of encrypting .NET data. After
reading this article you will be able to encrypt data using AES, test
AES-based software, and use AES encryption in your systems.
MD5 is not an encryption algorithm. It's a one-way hash. A one-way hash algorithm is suitable for authenticating users because you only ever hash their entered password (and compare it with the saved hash). You cannot decrypt a hash and display their passwords.
You need an encryption algorithm.
I am creating an application which stores multiple passwords of a
user. First user has to provide his/her user-name plus password, and
after successful login he'll be given all his saved passwords.
Since you are using C#, I'm assuming you are working on Windows and not a Mono project. First, the user proved his/her identity when they logged on, so there's no need to ask them to do so again.
Second, use Data Protection API (DPAPI). Its the standard way of storing user secrets on a Windows system. (cf Writing Secure Code, Chapter 9, p. 305). On earlier version of .Net, you will need to interop. On later versions of .Net (3.5, IIRC), it is available via the CLR.
Finally, MD5 is broken so it should not be used for cryptographic purposes. NIST recommends a security level of 112 bits (cf, Special Publication 800-57). Ditto for ECRYPT.
If you must discard DPAPI, use SHA-224 or higher as the hash for a password based key derivation function. Encrypt the file with 3-key TDEA, AES, Camellia, etc. Use an authenticated encryption mode (EAX, CCM, GCM) to detect tampering. If you don't have an authenticated encryption mode, you will need to add authenticity assurances yourself with a CMAC or HAMC (DPAPI does it for you).
Jeff

How secure is ProtectedData.Protect (DPAPI)?

Suppose someone gets access all of my hard disk, I guess the weak spot would be my windows password. Without knowing/being able to retrieve that, the data should be pretty much safe, shouldn't it?
I'm asking specifically because of the EFS entry in wikipedia which states that
In Windows 2000, the local administrator is the default Data Recovery Agent, capable of decrypting all files encrypted with EFS by any local user.
and EFS happens to use DPAPI. So does the same apply to my own data protected using this:
ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser);
And if that is indeed the case, how could I prevent it?
[Edit] N.B. I'm trying to store credentials for a winforms app so that the user does not have to enter their password every time they login. In other words, if someone is able to login as that user (i.e. know the user password), then they might as well be able read the encrypted data.
Which - not coming from a windows background - now makes me wonder - can't the local admin login as any local user anyway? In that case I shouldn't be concerned about the admin being able to retrieve passwords anyway...
[Edit2] As google reveals, it looks like an Administrator cannot just login as any user without resetting/changing their password first. So my question still seems relevant...
EFS uses DPAPI, not the other way around. And Administrator can't read your key just like that.
Before forgetting about DPAPI, I would consider the alternatives. If you encrypt the file yourself,
You must select a strong algorithm and implement it well.
You will need a key. Where will it be ?
You will store the key in a file somewhere on your drive.
That key is sensitive, obviously, you will want to encrypt it
Goto 1
DPAPI does 1 to 3 well. 4 and 5 are moot. If a Windows password is not enough to protect data, ask yourself why it is enough to CRUD that data in the first place.
For better security, you can consider not saving the data but a (salted) hash of it, if possible. It makes your data write only, though. For example, if you want to verify a customer license number :
Save a salted hash value of it
Run the same hash on the salted license number you want to verify,
Compare the two. It they match, the license is valid.
If you must read back encrypted data and a locally encrypted key is not enough, consider encrypting your application key (step 2 above) with a private key stored on a smart card.
Either way, remember that things happens. You always need a backup key somewhere.
See this article on DPAPI Security. Basically, it is as secure as your Windows password -- if your password is reset by an administrator, the decryption key will be lost. The major attack vectors you'll need to look at are:
Password disclosure: "shoulder surfing", sticky notes, etc.
Capture of the computer's accounts database and the use of a password cracker
Online attack by "drive-by download", removable media AutoPlay, etc.
Capture of a password reset disk, if you've made one
Physical installation of a key-logging device or other "bug"
DPAPI can be used both with and without optional entropy. There are only two ways DPAPI blobs without optional entropy can be compromised:
A domain admin can directly retrieve anyone's history of DPAPI master keys at any time. Nothing else is required. These can be used to decrypt all blobs. Local administrators cannot do this.
The user's Windows credentials are compromised.
If you use optional entropy then the data cannot be decrypted by anyone who doesnt know the value. The entropy may be derived from a password required to launch the application etc. Without the value, the data is lost forever.
EFS works differently. The user's key is protected using DPAPI for his profile, but the decryption key for the file itself is additionally directly encrypted with the administrator's public key as well. Therefore a domain admin can access the files.

Secure Password Storage and Transfer

I'm developing a new user store for my organisation and am now tackling password storage. The concepts of salting, HMAC etc are all fine with me - and want to store the users' passwords either salted and hashed, HMAC hashed, or HMAC salted and hashed - not sure what the best way will be - but in theory it won't matter as it will be able to change over time if required.
I want to have an XML & JSON service that can act as a Security Token Service for client-side apps.
I've already developed one for another system, which requires that the client double-encrypts a clear-text password using SHA1 first and then HMACSHA1 using a 128 unique key (or nonce) supplied by the server for that session only.
I'd like to repeat this technique for the new system - upgrading the algo to SHA256 (chosen since implementations are readily available for all aforementioned platforms - and it's much stronger than SHA1) - but there is a problem.
If I'm storing the password as a salted hash in the user-store, the client will need to be sent that salt in order to construct the correct hash before being HMACd with the unique session key. This would completely go against the point of using a salt in the first place. Equally, if I don't use salt for password storage, but instead use HMAC, it's still the same problem.
At the moment, the only solution I can see is to use naked SHA256 hashing for the password in the user store, so that I can then use this as a starting point on both the server and the client for a more secure salted/hmacd password transfer for the web service.
This still leaves the user store vulnerable to a dictionary attack were it ever to be accessed; and however unlikely that might be - assuming it will never happen simply doesn't sit well with me.
Greatly appreciate any input.
HTTPS is the best solution for this problem.
You are throwing a lot of crypto primitives at this problem in hopes that it will go away. In general the protocol that you are proposing seems to wasteful of resources, I recommend doing research into other authentication protocols and think of ways of simplifying your protocol. Practical Cryptography is an excellent book.
The biggest problem is see is in transfer of secrets between the client and server. In order to implement this correctly you need to use a Diffie-Hellman key exchange. Luckily one has already been written in javascript:
http://enanocms.org/News:Article/2008/02/20/Diffie_Hellman_key_exchange_implemented
Another problem is that i don't see how the client can determine that its talking to the correct server. SSL uses asymmetric cryptography, backed by a PKI, which you will not be able to implement in JavaScript.
A message digest is not an encryption algorithm. It is never okay to spill a password hash, where as cipher text is meant to protect against an eavesdropping.
Spilling a password salt to an attacker will make your passwords less secure. If the attacker has a salt then they can use a dictionary to attack the password, without the salt they will have to guess randomly, making the password storage system far more robust.
A salt does not need to be secret - it must be unique. a salt is designed to mitigate the threat of two users having the same password and hence the same resulting hash. so you can use the user's name as the salt if you wish. a salt makes a dictionary attack much much harder because the attacker has to compute each result for every dictionary word and every possible salt.
in my opinion, i would use a password-based key derivation function (PBKDF) with a high iteration count and a salt.
http://www.bing.com/search?q=pbkdf2
Here's sample code in C#, but it's avail in most any popular framework today
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

Keeping passwords in the registry as "secrets"

I need to store my users' name/password somewhere (preferably the Registry) so my .Net application can use them to log in to some remote service on behalf of the user. I know it's possible to store values in the registry as "secrets", which means their encrypted using the Windows domain user token or something. In other words, I don't want to have to deal with the encryption myself.
To clarify: I can't store hashes of the password or salt them or anything. These credentials are for a 3rd party system and the only way for me to be able to login to this system on behalf of my users is to somehow keep their credentials and be able to restore them.
So anyway, I remember vaguely there's such a place in the registry, but the details are murky. And I need to do it in C# (though if it's simple registry access it shouldn't matter).
Edit: One more thing, it should persist between Windows user sessions (IOW it doesn't help me if the password in unreadable after the user logs off and on).
You're probably thinking of the Data Protection API. Search MSDN or read some blogs and see if that'll work for you.
You can try using System.Security.Cryptography.ProtectedData, which can encrypt them using a per user key. http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx.
It's not completely secure, since code running as the user could decrypt the data.
Keep in mind that you're not really securely storing anything if you can automatically (without user input) retrieve the password. Using RSA, symmetric, or other encryption doesn't make a difference so long as you store the decoding key within your application. Once anyone gets the key, the secret's out.
However, the Data Protection API mentioned above should protect passwords from other users on the same machine. (It sounds like DPAPI uses your login credentials for encryption.)
For a few more options, check out the msdn page for Threat Mitigation.
You should never store credentials as plaintext. Use a symmetric key cipher. Take the password out at runtime. See the MSDN reference on Cryptography functions.

Categories