Atif Imtiaz
Atif Imtiaz

Reputation: 225

Encryption Engine

Right now i am making a library that will be performing common tasks in C# .Net. basically i am targetting beginners of C# so that they can take benefit from my library and use it to minimize the difficulties they are having. I am currently adding an encryption functionality into my library, and i have got some success. But my encryption criteria is not very difficult and complex. so that in future any hacker could break in through and decrypt important data (i.e., passwords etc). so please tell me how can i write my own complex criteria to encrypt passwords. This library is intended to be free and for beginners.

Thanks

Upvotes: 3

Views: 1497

Answers (4)

Stefano Altieri
Stefano Altieri

Reputation: 4628

For didactic purposes you could use the .net File encryption system (very easy!!)

System.IO.File.Encrypt("file.txt")
System.IO.File.Decrypt("file.txt")

Files can be decrypted just from the same machine.

Upvotes: 0

Joe Ratzer
Joe Ratzer

Reputation: 18569

I advise you don't write your own encryption engine, without a very good reason, when there are many already out there - as a start have a look at the encryption API in Enterprise Library. It's quite beginner friendly.

If you're still determined to write your own, still look at Enterperise Library, and others like BouncyCastle, to see how other frameworks are put together - you'll learn a lot and it's the best way to try and improve what's out there.

Upvotes: 5

SynerCoder
SynerCoder

Reputation: 12776

You could write easy to use wrappers around the .NET encryption methods.

Aes example (my own wrapper):

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

using Synercoding.CodeGuard;

namespace Synercoding.Encryption.Symmetrical
{
    /// <summary>
    /// A class to Encrypt and Decrypt with Rijndael AES encryption
    /// </summary>
    public sealed class AesEncryption : IDisposable
    {
        private byte[] m_salt;
        private RijndaelManaged m_aesAlg = new RijndaelManaged(); // RijndaelManaged object used to encrypt/decrypt the data.

        /// <summary>
        /// Create a new AesEncryption object with the standard salt
        /// </summary>
        public AesEncryption() : this("850nW94vN39iUx") { }

        /// <summary>
        /// Create a new AesEncryption object with the specified salt
        /// </summary>
        /// <param name="salt">The salt used for salting the key. Must be atleast 8 chars long</param>
        public AesEncryption(string salt)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(salt), "param salt can't be null or empty.");
            Guard.Requires<ArgumentException>(salt.Length >= 8, "param salt must be atleast 8 chars long.");
            m_salt = Encoding.ASCII.GetBytes(salt);
        }

        /// <summary>
        /// The salt in ASCII string format
        /// </summary>
        public string SaltString
        {
            get
            {
                return Encoding.ASCII.GetString(m_salt);
            }
        }

        /// <summary>
        /// The salt that is used for the key and IV generation.
        /// </summary>
        public byte[] Salt
        {
            get
            {
                return m_salt;
            }
        }

        /// <summary>
        /// Encrypt the given string using AES.  The string can be decrypted using 
        /// DecryptStringAES().  The sharedSecret parameters must match.
        /// </summary>
        /// <param name="plainText">The text to encrypt.</param>
        /// <param name="sharedSecret">A password used to generate a key for encryption.</param>
        public string EncryptStringAES(string plainText, string sharedSecret)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(plainText), "param plainText can't be null or empty");
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(sharedSecret), "param sharedSecret can't be null or empty");
            Guard.Requires<InvalidOperationException>(m_aesAlg != null, "this object is already disposed");

            string outStr = null;                       // Encrypted string to return

            // generate the key from the shared secret and the salt
            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, Salt);

            m_aesAlg.Key = key.GetBytes(m_aesAlg.KeySize / 8);
            m_aesAlg.IV = key.GetBytes(m_aesAlg.BlockSize / 8);


            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = m_aesAlg.CreateEncryptor(m_aesAlg.Key, m_aesAlg.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {

                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                }

                outStr = Convert.ToBase64String(msEncrypt.ToArray());
            }

            // Return the encrypted bytes from the memory stream.
            return outStr;
        }

        /// <summary>
        /// Decrypt the given string.  Assumes the string was encrypted using 
        /// EncryptStringAES(), using an identical sharedSecret.
        /// </summary>
        /// <param name="cipherText">The text to decrypt.</param>
        /// <param name="sharedSecret">A password used to generate a key for decryption.</param>
        public string DecryptStringAES(string cipherText, string sharedSecret)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(cipherText), "param cipherText can't be null or empty");
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(sharedSecret), "param sharedSecret can't be null or empty");
            Guard.Requires<InvalidOperationException>(m_aesAlg != null, "this object is already disposed");

            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // generate the key from the shared secret and the salt
            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, Salt);

            m_aesAlg.Key = key.GetBytes(m_aesAlg.KeySize / 8);
            m_aesAlg.IV = key.GetBytes(m_aesAlg.BlockSize / 8);

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = m_aesAlg.CreateDecryptor(m_aesAlg.Key, m_aesAlg.IV);
            // Create the streams used for decryption.                
            byte[] bytes = Convert.FromBase64String(cipherText);
            using (MemoryStream msDecrypt = new MemoryStream(bytes))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))

                        // Read the decrypted bytes from the decrypting stream
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                }
            }

            return plaintext;
        }

        public void Dispose()
        {
            if (m_aesAlg != null)
            {
                m_aesAlg.Clear();
                m_aesAlg.Dispose();
                m_aesAlg = null;
            }
        }
    }
}

MD5 (hash) example:

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

using Synercoding.CodeGuard;

namespace Synercoding.Encryption.Hashing
{
    /// <summary>
    /// Class to verify and generate MD5 hashes
    /// </summary>
    public static class MD5Hash
    {
        /// <summary>
        /// Creates a MD5 hexadecimal string based on the input
        /// </summary>
        /// <param name="input">The string to hash</param>
        /// <returns>A MD5 hex string</returns>
        public static string GetHash(string input)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            using (MD5 md5Hash = MD5.Create())
            {
                // Convert the input string to a byte array and compute the hash.
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

                // Loop through each byte of the hashed data 
                // and format each one as a hexadecimal string.
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        /// <summary>
        /// Creates a MD5 hexadecimal string based on the input
        /// </summary>
        /// <param name="input">The string to hash</param>
        /// <returns>A MD5 hash in byte format</returns>
        public static byte[] GetByteHash(string input)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");

            byte[] data;
            using (MD5 md5Hash = MD5.Create())
            {
                // Convert the input string to a byte array and compute the hash.
                data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            }

            return data;
        }

        /// <summary>
        /// Verifies the input with the hash.
        /// </summary>
        /// <param name="input">The input to compare</param>
        /// <param name="hash">The hash to compare the input with</param>
        /// <returns>True is the input validates.</returns>
        public static bool VerifyHash(string input, string hash)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(hash), "param hash can't be null or empty");
            Guard.Requires<ArgumentNullException>(hash.Length == 32, "param hash must be 32 chars long");

            // Hash the input.
            string hashOfInput = GetHash(input);

            // Create a StringComparer an compare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Verifies the input with the hash.
        /// </summary>
        /// <param name="input">The input to compare</param>
        /// <param name="hash">The hash to compare the input with</param>
        /// <returns>True is the input validates.</returns>
        public static bool VerifyHash(string input, byte[] hash)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");
            Guard.Requires<ArgumentNullException>(hash != null, "param hash can't be null");
            Guard.Requires<ArgumentNullException>(hash.Length == 128 / 8, "param hash must be 128bits (16 bytes) long");

            // Hash the input.
            byte[] hashOfInput = GetByteHash(input);

            if (hashOfInput.SequenceEqual(hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

SHA512 (hash) example:

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

using Synercoding.CodeGuard;

namespace Synercoding.Encryption.Hashing
{
    /// <summary>
    /// Class to verify and generate SHA512 hashes
    /// </summary>
    public static class SHA512Hash
    {
        /// <summary>
        /// Creates a SHA512 hexadecimal string based on the input
        /// </summary>
        /// <param name="input">The string to hash</param>
        /// <returns>A SHA512 hex string</returns>
        public static string GetHash(string input)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            using (SHA512 SHA512Hash = SHA512.Create())
            {
                // Convert the input string to a byte array and compute the hash.
                byte[] data = SHA512Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

                // Loop through each byte of the hashed data 
                // and format each one as a hexadecimal string.
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        /// <summary>
        /// Creates a SHA512 hash based on the input
        /// </summary>
        /// <param name="input">The string to hash</param>
        /// <returns>A SHA512 hash in byte format</returns>
        public static byte[] GetByteHash(string input)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");

            byte[] data;

            using (SHA512 SHA512Hash = SHA512.Create())
            {
                // Convert the input string to a byte array and compute the hash.
                data = SHA512Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            }

            return data;
        }

        /// <summary>
        /// Verifies the input with the hash.
        /// </summary>
        /// <param name="input">The input to compare</param>
        /// <param name="hash">The hash to compare the input with</param>
        /// <returns>True is the input validates.</returns>
        public static bool VerifyHash(string input, string hash)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(hash), "param hash can't be null or empty");
            Guard.Requires<ArgumentNullException>(hash.Length == 128, "param hash must be 128 chars long");

            // Hash the input.
            string hashOfInput = GetHash(input);

            // Create a StringComparer an compare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Verifies the input with the hash.
        /// </summary>
        /// <param name="input">The input to compare</param>
        /// <param name="hash">The hash to compare the input with</param>
        /// <returns>True is the input validates.</returns>
        public static bool VerifyHash(string input, byte[] hash)
        {
            Guard.Requires<ArgumentNullException>(!string.IsNullOrEmpty(input), "param input can't be null or empty");
            Guard.Requires<ArgumentNullException>(hash != null, "param hash can't be null");
            Guard.Requires<ArgumentNullException>(hash.Length == 512 / 8, "param hash must be 512bits (64 bytes) long");

            // Hash the input.
            byte[] hashOfInput = GetByteHash(input);

            if (hashOfInput.SequenceEqual(hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

Upvotes: 0

sujeesh
sujeesh

Reputation: 498

Do not go for your own library when there are lot of existing libraries are there. You wont get benefited out of this and will be of no use. A proverb: Do not buy a cafeteria just for drinking a cup of tea.

Upvotes: 2

Related Questions