Tuesday, 29 January 2019

C# Encrypt and Decrypt Password.

This article is about to encrypt and decrypt a string value. I have created the following class to encrypt the password and save in database. This class provides 3 methods as bellow:

1. CreateSalt(): This generates a salt key to encrypt the string value.
2. Encrypt(string plainText, string saltKey): This method Encrypts the string value with passed saltKey. You can generate a salt key using "CreateSalt()" method.
3. Decrypt(string cipherText, string saltKey): This method Decrypts the encrypted string value with passed saltKey. You have to use the same salKey, that you have used to encrypt the string value.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace YOUR_NAMESPACE
{
    public class CryptoUtils
    {
        private const CipherMode cipherMode = CipherMode.CBC;
        private const PaddingMode paddingMode = PaddingMode.ISO10126;
        private const string defaultVector = "fdsah123456789";
        private const int iterations = 2;

        public static string CreateSalt()
        {
            //Generate a cryptographic random number.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[20];
            rng.GetBytes(buff);

            // Return a Base64 string representation of the random number.
            return Convert.ToBase64String(buff);
        }

        /// <summary>
        /// To encrypt the plain text. This produces the different encrypted text for same string everytime.
        /// </summary>
        /// <param name="plainText">String value to encrypt</param>
        /// <returns></returns>
        public static string Encrypt(string plainText, string saltKey)
        {
            byte[] clearData = Encoding.Unicode.GetBytes(plainText);
            byte[] encryptedData;
            var crypt = GetCrypto(saltKey);
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, crypt.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearData, 0, clearData.Length);
                    //cs.FlushFinalBlock(); //Have tried this active and commented with no change.
                }
                encryptedData = ms.ToArray();
            }
            //Changed per Xint0's answer.
            return Convert.ToBase64String(encryptedData);
        }

        public static string Decrypt(string cipherText, string saltKey)
        {
            //Changed per Xint0's answer.
            if (!String.IsNullOrEmpty(cipherText))
            {
                byte[] encryptedData = Convert.FromBase64String(cipherText);
                byte[] clearData;
                var crypt = GetCrypto(saltKey);
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, crypt.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(encryptedData, 0, encryptedData.Length);
                        //I have tried adding a cs.FlushFinalBlock(); here as well.
                    }
                    clearData = ms.ToArray();
                }
                return Encoding.Unicode.GetString(clearData);
            }
            else
            {
                return null;
            }
        }

        private static Rijndael GetCrypto(string passphrase)
        {
            var crypt = Rijndael.Create();
            crypt.Mode = cipherMode;
            crypt.Padding = paddingMode;
            crypt.BlockSize = 256;
            crypt.KeySize = 256;
            crypt.Key = new Rfc2898DeriveBytes(passphrase, Encoding.Unicode.GetBytes(defaultVector), iterations).GetBytes(32);
            crypt.IV = new Rfc2898DeriveBytes(passphrase, Encoding.Unicode.GetBytes(defaultVector), iterations).GetBytes(32);
            return crypt;
        }
    }
}

Usage: Use the above class methods as following:

var saltKey = CryptoUtils.CreateSalt();
var encryptedData = CryptoUtils.Encrypt("User@12345!@#", saltKey);
var decryptedData = CryptoUtils.Decrypt(encryptedData, saltKey);

1 comment:

  1. Thanks for appreciate. Sure I will try your tool and will recommend to people in such requirements.

    ReplyDelete