Take the 2-minute tour ×

The bottom line is to create a custom FTP Authentication Provider. In order to do this one must inherit from IFtpAuthenticationProvider interface and then register that assembly in GAC. After that the assembly needs to be registered in IIS's FTP settings.

In order for this to be accomplished I have to use the database which holds my user information in the database from the custom Membership and Role providers we have developed previously. So, that means I have to use a local class library app.config file and read it with ConfigurationManager.OpenMappedExeConfiguration(). I read the connection strings from there and I'm even able to provide it to Linq-To-Sql classes dynamically. No problem there.

Next, I try to create a class that inherits from SqlMembershipProvider so that I can use it's own system to decrypt the password for a user. But, the problem is that it has to read machineKey values from configuration. The only way you can provide custom configuration to a SqlMembershipProvider is trough it's Initialize method (which is not intended for us to use it in our code anyway). But anyway I tried and failed. I've been able to provide it a custom membership settings but not machineKey settings.

So, I decided to go radical. I said: I have the decryptionKey from machineKey so I'll try to decrypt the password manually.

So far I've tried using RijndaelManaged:

    private string UnEncodePassword(string encodedPassword, string secretKey)
        string password = encodedPassword;

        var keyBytes = new byte[16];
        var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
        Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));

        RijndaelManaged rm = new RijndaelManaged
            Mode = CipherMode.CBC,
            Padding = PaddingMode.PKCS7,
            KeySize = 128,
            BlockSize = 128,
            Key = keyBytes,
            IV = keyBytes

        var encryptedBytes = Convert.FromBase64String(encodedPassword);
        password = Encoding.UTF8.GetString(Decrypt(encryptedBytes, rm));

        return password;

I'm kind of aware that I'm shooting blanks here since I'm not eve sure what kind of padding is used and most importantly even if I could I'm not hitting the right IV. The best I'v done so far is to get some junkish response like: �21l�<��(�\t��].

So I need some pointers. Even suggestions on how to tackle this whole issue from another perspective are welcome.


Just to make things a little bit more clear. I'm not trying to crack the password or anything. I have the password and I have the decryptionKey etc. I just want to find a way to Encrypt/Decrypt it so that I can make a user validation.
I am fully aware that encrypting/decrypting passwords are not the best approach in the first place, but there are reasons why that is being done that way.

share|improve this question
I has two thoughts: 1. IV never will be the same is keyBytes. It can be constant or stored somewhere. Try all 0xFF or all 0x00. 2. Why you need decrypted user password? I think, you need method to authenticate password provided by user against password in database. Right? –  werewindle Dec 29 '11 at 14:47
And other thought. It is weird to store encrypted password in database. Almost all software stores only password hashes. –  werewindle Dec 29 '11 at 14:49
@werewindle - 2. yes, but the password is encrypted. I need to decrypt it first so I can compare it. –  Bojan Skrchevski Dec 29 '11 at 14:49
@BojanSkrchevski - Please do not store or use a system where you are able to decrypt a user's passwords. A system that allows you to do this is NOT secure. Encrypt the user's input and compare that. The memembership role functionality built into ASP.NET by default does user/password the correct way, which means, you CANNOT decrypt the password without knowing plaintext password, even then your onl comparing the two values not decrypting the stored data. –  Ramhound Dec 29 '11 at 15:09
I've got one: stackoverflow.com/questions/4941826/… –  Bojan Skrchevski Dec 29 '11 at 15:38
show 5 more comments

3 Answers

up vote 1 down vote accepted

I do agree with the others that hashed passwords are generally more secure that enrypted ones.

But because you can't choose why do you have to use the Encryption or Decription methods from MembershipProvider (btw, I don't even think it's possible).

Why don't you create your own encryption methods and use them in the web application and your class library.

share|improve this answer
I never gave it thought. It can definetly be one way to solve the problem. –  Bojan Skrchevski Dec 29 '11 at 16:28
-1 this is a terrible solution, this has all the costs of replacing the encrypted passwords with a wheel reinvented AND technically flawed solution. If you're going to replace all the passwords, they should be replaced with hashes. –  Chris Marisic Dec 29 '11 at 18:21
@ChrisMarisic - as I said previously that is a requirement and I cannot change it. Having that into consideration, this is the solution that is most applicable. –  Bojan Skrchevski Dec 29 '11 at 18:26
add comment

You should not be decrypting passwords. You should be comparing password hashes.

Passwords should not be stored with reversible encryption. Passwords are meant to be stored as hashes (not MD5 it's too weak).

Regarding your comment above, you do not need to decrypt passwords to compare them. You want to compare the hashes, not the original values. The system should not be able to get the original text of a password. Using the built in ASP.NET membership providers correctly stores passwords as hashes. This is likely why you can't decrypt them, they're meant to be impossible to decrypt.

Edit: In regards to the fact you use passwordFormat="Encrypted" for the SQL membership provider. With this fact you can either encrypt the password in the same format, with the same padding, cipherMode, and IV (you will need to query this from the SQL database) and then just compare the encrypted password values. This is likely unneeded work. You really just want to invoke the Membership's logon function in code with the username/password combination and verify whether it is successful or not. You will need to make sure the machine keys and relevant pieces match in both systems otherwise you won't be able to succeed.

You really want to plan to move to hashed passwords however, storing encrypted passwords as opposed to hashed passwords is nearly pointless. It is only just slightly better than storing them in plain text.

share|improve this answer
First of all at this point it's not my decision. Just treat that part as someone else did it and I have to take it from there. –  Bojan Skrchevski Dec 29 '11 at 14:54
Do note, that impossible in regards to security is ALWAYS a relative term. With enough money and time, generally every single encryption or hashing scheme can eventually be decrypted. The goal is to just make it take years or 10,000s of years for it to happen. –  Chris Marisic Dec 29 '11 at 14:55
Update on your edit. Do you have a suggestion how this can be solved? –  Bojan Skrchevski Dec 29 '11 at 14:55
@BojanSkrchevski unless you're using custom hand built membership providers that are writing reversible encrypted passwords to the database the passwords are hashes in the database. You cannot decrypt them. –  Chris Marisic Dec 29 '11 at 14:56
I don't think you got my point. I already have the decryptionKey. I just want to find a way to see if the user entered the correct password, regardless. –  Bojan Skrchevski Dec 29 '11 at 14:57
show 11 more comments

You don't typically need to store encrypted passwords, unless you want a form of password-recovery which lets the user see their current password. It's usually a bad idea and it does require a lot more work.

Conventionally, you should only store a salted hash of the password in your database. Hashing is a one-way operation (so nobody can ever decrypt the information to find out the passwords if your database is compromised).

To detect whether a user's password matches the one you have stored, you only need to hash their password with the same salt you used to hash the value in the database. If the two hashes match, the user has provided a correct password.

The authenticate algorithm should look something like this:

  1. Get salt for hashing (could be that you use a salt unique to each user, or a global one)
  2. Generate a hash of the user's password.
  3. Compare the hashed password to the one stored in your database for the username specified (if using LINQ-to-SQL, a simple Any statement can do this).
  4. Return a value to indicate success or failure.
share|improve this answer
add comment

Your Answer


