开发者

Password encryption/decryption code in .NET

I want simple encryption and decryption of password in C#. How to save the passw开发者_StackOverfloword in encrypted format in database and retrieve as original format by decryption?


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);
    }


EDIT: this is a very old answer. SHA1 was deprecated in 2011 and has now been broken in practice. https://shattered.io/ Use a newer standard instead (e.g. SHA256, SHA512, etc).

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));
    }


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());
            }
        }
    }


First create a class like:

public class Encryption
    { 
        public static string Encrypt(string clearText)
        {
            string EncryptionKey = "MAKV2SPBNI99212";
            byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(clearBytes, 0, clearBytes.Length);
                        cs.Close();
                    }
                    clearText = Convert.ToBase64String(ms.ToArray());
                }
            }
            return clearText;
        }

        public static string Decrypt(string cipherText)
        {
            string EncryptionKey = "MAKV2SPBNI99212";
            byte[] cipherBytes = Convert.FromBase64String(cipherText);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(cipherBytes, 0, cipherBytes.Length);
                        cs.Close();
                    }
                    cipherText = Encoding.Unicode.GetString(ms.ToArray());
                }
            }
            return cipherText;
        }
    }

**In Controller **

add reference for this encryption class:

using testdemo.Models

public ActionResult Index() {
            return View();
        }
        [HttpPost]
        public ActionResult Index(string text)
        {
            if (Request["txtEncrypt"] != null)
            {
                string getEncryptionCode = Request["txtEncrypt"];
                string DecryptCode = Encryption.Decrypt(HttpUtility.UrlDecode(getEncryptionCode));
                ViewBag.GetDecryptCode = DecryptCode;
                return View();
            }
            else {
                string getDecryptCode = Request["txtDecrypt"];
                string EncryptionCode = HttpUtility.UrlEncode(Encryption.Encrypt(getDecryptCode));
                ViewBag.GetEncryptionCode = EncryptionCode;
                return View();
            }

        }

In View

<h2>Decryption Code</h2>
@using (Html.BeginForm())
{
    <table class="table-bordered table">
        <tr>
            <th>Encryption Code</th>
            <td><input type="text" id="txtEncrypt" name="txtEncrypt" placeholder="Enter Encryption Code" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <span style="color:red">@ViewBag.GetDecryptCode</span>
            </td>
        </tr>
        <tr>
                <td colspan="2">
                    <input type="submit" id="btnEncrypt" name="btnEncrypt"value="Decrypt to Encrypt code" />
                </td>
            </tr>
    </table>
}
    <br />
    <br />
    <br />
    <h2>Encryption Code</h2>
@using (Html.BeginForm())
{
    <table class="table-bordered table">
        <tr>
            <th>Decryption Code</th>
            <td><input type="text" id="txtDecrypt" name="txtDecrypt" placeholder="Enter Decryption Code" /></td>
        </tr>

        <tr>
            <td colspan="2">
                <span style="color:red">@ViewBag.GetEncryptionCode</span>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" id="btnDecryt" name="btnDecryt" value="Encrypt to Decrypt code" />
            </td>
        </tr>
    </table>
}


This question will answer how to encrypt/decrypt: Encrypt and decrypt a 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'll then either save it in a varchar or a blob, depending on how long your encrypted message is, but for a password 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 it's best 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.


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?


 string clearText = txtPassword.Text;
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }


Do not encrypt/decrypt passwords, that is a significant security vulnerability. HASH passwords, using a strong hash algorithm such as PBKDF2, bcrypt, scrypts, or Argon.

When the user sets their password, hash it, and store the hash (and salt).

When the user logs in, re-hash their provided password, and compare it to the hash in the database.


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);
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜