views:

2032

answers:

8

I want simple encryption and decryption of password in C#. how to save the password in encrypted format in database and retrieve as original format by decryption, kindly anyone help with sample code.

+5  A: 

If your answer to the question in my comment is "No", here's what I use:

    public static byte[] HashPassword(string password)
    {
        var provider = new SHA1CryptoServiceProvider();
        var encoding = new UnicodeEncoding();
        return provider.ComputeHash(encoding.GetBytes(password));
    }
Cogwheel - Matthew Orlando
SHA1 has been compromised, as shown here: http://okami-infosec.blogspot.com/2007/01/hash-sha-1-compromised.html
James Black
I don't believe any of the SHA-2 family has been compromised, you may want to use one of these: http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-2_family
James Black
But, it depends on how secure, or how paranoid, you will be. At the university I was very paranoid.
James Black
A: 

One of the simplest methods of encryption (if you absolutely MUST make one up yourself since .NET has such awesome encryption libraries already [as provided by Cogwheel just before me]) is to XOR the ASCII value of each character of the input string against a known "key" value. XOR functionality in C# is accomplished using the ^ key I believe.

Then you can convert the values back from the result of the XOR to ASCII Chars, and store them in the database. This is not highly secure, but it is one of the easiest encryption methods.

Also, if using an access database, I've found that some characters when put in front of a string make the entire field unreadable when opening the database itself. But the field is still readable by your app even though it is blank to a malicious user. But who uses access anymore anyway right?

Jrud
I know, right? *look around innocently* (Actually, I'm in the middle of writing a proposal to get rid of the system I inherited and enter the 21st century)
Cogwheel - Matthew Orlando
God help us all :(
zebrabox
I feel his pain. The only reason I knew that about access is because I was dealing with a project at my job that used an old access Database. It was already being up-converted at the time, but that didn't stop the customers from requesting new features of the old version.
Jrud
+1  A: 

This question will answer how to encrypt/decrypt: http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-c

You didn't specify a database, but you will want to base-64 encode it, using Convert.toBase64String. For an example you can use: http://www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx

You then either save it in a varchar or a clob, depending on how long your encrypted message is, but for a password a varchar should work.

The examples above will also cover decryption after decoding the base64

UPDATE:

In actuality you may not need to use base64 encoding, but I found it helpful, in case I wanted to print it, or send it over the web. If the message is long enough I found it helpful to compress it first, then encrypt, as it is harder to use brute-force when the message was already in a binary form, so it would be hard to tell when you successfully broke the encryption.

James Black
Besides portability, are there any substantial benefits to using base-64 instead of binary (if the db supports it)?
Cogwheel - Matthew Orlando
No benefit, other than the fact that it is easier to store, to treat as a string, and if you need to move it around I find it easier. I am not a fan of using blobs, mainly because I spent so long on mysql where they really didn't have support, so I just think that way. Besides, if you want to print out the encrypted message then it is in a printable fashion, which can be handy, just to see what happened.
James Black
Good point... I converted the hash to a string once during debugging and compared the resulting kanji ><
Cogwheel - Matthew Orlando
+1  A: 

Here you go. I found it somewhere on the internet. Works well for me.

    /// <summary>
    /// Encrypts a given password and returns the encrypted data
    /// as a base64 string.
    /// </summary>
    /// <param name="plainText">An unencrypted string that needs
    /// to be secured.</param>
    /// <returns>A base64 encoded string that represents the encrypted
    /// binary data.
    /// </returns>
    /// <remarks>This solution is not really secure as we are
    /// keeping strings in memory. If runtime protection is essential,
    /// <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="plainText"/>
    /// is a null reference.</exception>
    public string Encrypt(string plainText)
    {
        if (plainText == null) throw new ArgumentNullException("plainText");

        //encrypt data
        var data = Encoding.Unicode.GetBytes(plainText);
        byte[] encrypted = ProtectedData.Protect(data, null, Scope);

        //return as base64 string
        return Convert.ToBase64String(encrypted);
    }

    /// <summary>
    /// Decrypts a given string.
    /// </summary>
    /// <param name="cipher">A base64 encoded string that was created
    /// through the <see cref="Encrypt(string)"/> or
    /// <see cref="Encrypt(SecureString)"/> extension methods.</param>
    /// <returns>The decrypted string.</returns>
    /// <remarks>Keep in mind that the decrypted string remains in memory
    /// and makes your application vulnerable per se. If runtime protection
    /// is essential, <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="cipher"/>
    /// is a null reference.</exception>
    public string Decrypt(string cipher)
    {
        if (cipher == null) throw new ArgumentNullException("cipher");

        //parse base64 string
        byte[] data = Convert.FromBase64String(cipher);

        //decrypt data
        byte[] decrypted = ProtectedData.Unprotect(data, null, Scope);
        return Encoding.Unicode.GetString(decrypted);
    }
this. __curious_geek
A: 

you may compute hash

result = md5.ComputeHash(data);

and save in in db

On Verify method compute hash from input string and check it against db store item.

Arseny
+2  A: 

You could use encryption, but what's usually used to code a password is a hash:

string hash = Convert.ToBase64(
  System.Security.Cryptography.MD5.Create()
  .ComputeHash(Encoding.UTF8.GetBytes(password))
);

It's a one-way process, so you can not "de-hash" the result to get the password. To verify the password you get the hash code of what the user entered, and check if the result is the same as what's stored in the database.

Adding salt to the password is easy. You either use a known string that is different for most users like the user name, or create a random string that is stored along with the hash code, and concatenate with the password before coding it.

Guffa
MD5 is not considered secure. Why would you use anything less than SHA512?
Quick Joe Smith
@Joe: Good point. It depends on the requirements. In a few years every encryption that exists today will likely be considered unsafe...
Guffa
+1  A: 

You can use the managed .Net cryptography library, then save the encrypted string into the database. When you want to verify the password you can compare the stored database string with the hashed value of the user input. See here for more info about SHA512Managed

using System.Security.Cryptography;

    public static string EncryptSHA512Managed(string password)
    {
        UnicodeEncoding uEncode = new UnicodeEncoding();
        byte[] bytPassword = uEncode.GetBytes(password);
        SHA512Managed sha = new SHA512Managed();
        byte[] hash = sha.ComputeHash(bytPassword);
        return Convert.ToBase64String(hash);
    }
Case
+1  A: 

I use RC2CryptoServiceProvider.

    public static string EncryptText(string openText)
    {
        RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
        ICryptoTransform encryptor = rc2CSP.CreateEncryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv));
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                byte[] toEncrypt = Encoding.Unicode.GetBytes(openText);

                csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
                csEncrypt.FlushFinalBlock();

                byte[] encrypted = msEncrypt.ToArray();

                return Convert.ToBase64String(encrypted);
            }
        }
    }

    public static string DecryptText(string encryptedText)
    {
        RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
        ICryptoTransform decryptor = rc2CSP.CreateDecryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv));
        using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedText)))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                List<Byte> bytes = new List<byte>();
                int b;
                do
                {
                    b = csDecrypt.ReadByte();
                    if (b != -1)
                    {
                        bytes.Add(Convert.ToByte(b));
                    }

                }
                while (b != -1);

                return Encoding.Unicode.GetString(bytes.ToArray());
            }
        }
    }
Pavel Belousov