//--------------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        ///     Tests the encryption methods
        /// </summary>
        public static bool Test()
        {
            bool success = false;

            //-----------------------------------------------------------------------------------------------------------------------------------------------------------
            // Test the general encryption stuff ...
            SecureString tempKey = MGLEncryption.GenerateKey();

            Console.WriteLine(tempKey);
            MGLEncryption.SetCryptKey = tempKey;

            StringBuilder testStr      = new StringBuilder("What a lovely __ time of it!");
            StringBuilder encryptedStr = MGLEncryption.Encrypt(testStr);
            StringBuilder decryptedStr = MGLEncryption.Decrypt(encryptedStr);
            bool          theSame      = MGLEncryption.Compare(testStr, encryptedStr);
            bool          theSameStr   = AreEqual(testStr, decryptedStr);
            bool          notTheSame   = MGLEncryption.Compare(new StringBuilder("Oh dear"), encryptedStr);

            StringBuilder htmledStr   = MGLEncryption.HTMLifyString(encryptedStr);
            StringBuilder deHtmledStr = MGLEncryption.DeHTMLifyString(htmledStr);
            bool          htmlWorking = MGLEncryption.AreEqual(deHtmledStr, encryptedStr);

            // Now test the password stuff ...
            SecureString tempKey2 = MGLEncryption.GenerateKey();

            Console.WriteLine(tempKey2);

            success = (theSame == true) && (theSameStr == true) && (notTheSame == false) && (htmlWorking == true);

            return(success);
        }
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        ///     Generates a long key from a set of input characters
        /// </summary>
        public static StringBuilder GetSalt(int saltLength)
        {
            /*
             *  Old simple approach to generating a random string - the Random class in C# is fundamentally flawed and will always
             *  produce the same set of "random" numbers in the same sequence!!!
             *  Here are our seed characters:
             *  string chars = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789_";
             *  Random random = new Random();
             *  string result = new string(
             *      Enumerable.Repeat(chars, saltLength)
             *      .Select(s => s[random.Next(s.Length)])
             *      .ToArray());
             */

            // New approach using dedicated random cryptographic class - Build a random list of characters to the specified length ...
            // use a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)
            RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();

            byte[] salt = new byte[saltLength];
            csprng.GetBytes(salt);

            StringBuilder base64Str = new StringBuilder(Convert.ToBase64String(salt));

            if (base64Str.Length > saltLength)
            {
                base64Str = MGLEncryption.SubstringStringBuilder(base64Str, 0, saltLength);
            }

            return(base64Str);
        }
Exemple #3
0
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        ///     Compares two passwords - note that this method includes a Threading element so that hackers cannot tell how similar strings are
        ///     by using code to time the comparison - e.g. a match on the first and second chars will be marginally slower than one that does not
        ///     match on the first character
        ///
        ///     The test password is UNencrypted, while the current password is fully encrypted ...
        /// </summary>
        public static bool Compare(StringBuilder testPassword, StringBuilder currentPassword)
        {
            bool success = false;

            string[] bits = null;

            try {
                // get the attributes from the current Password
                // have to conver it to a string unfortunately to split on the colons ....
                bits = currentPassword.ToString().Split(new string[] { ":" }, StringSplitOptions.None);

                int numIterations = 0;
                int.TryParse(bits[3], out numIterations);

                // Encrypt the test password
                StringBuilder encryptedTestPassword = Encrypt(testPassword, bits[1], bits[2], numIterations);

                // now do basic string comparison to compare the two strings!
                if (MGLEncryption.AreEqual(encryptedTestPassword, currentPassword) == true)
                {
                    success = true;
                }
            } catch (Exception ex) {
                Logger.LogError(9, "MGLPasswordHash - error occurred while comparing two passwords: " + ex.ToString());
            } finally {
                // always kill the array of bits
                bits = null;
            }

            // Now introduce a random response element, delaying by up to 100 ms. (0.1 seconds)
            Thread.Sleep(new Random().Next(0, 100));

            return(success);
        }
Exemple #4
0
        ////---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ///// <summary>
        /////     Generates a long key from a set of input characters
        /////     13-Oct-2015 - Use the MGLEncryption method instead ...
        ///// </summary>
        //public static string GetSalt(int saltLength) {

        //    // Use a dedicated random cryptographic class to build a random list of characters to the specified length ...
        //    // use a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)
        //    RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
        //    byte[] salt = new byte[saltLength];
        //    csprng.GetBytes(salt);

        //    string base64Str = Convert.ToBase64String(salt);

        //    return base64Str;
        //}


        //--------------------------------------------------------------------------------------------------------------------------------------------------------------
        private static bool TestEncryption()
        {
            bool success = false;

            //-----------------------------------------------------------------------------------------------------------------------------------------------------------
            // Test the general encryption stuff ...
            StringBuilder tempKey  = MGLEncryption.GetSalt(30);
            StringBuilder tempKey2 = MGLEncryption.GetSalt(30);

            // Test the mgl encryption 2 ...
            StringBuilder testPword2 = MGLPasswordHash.EncryptPassword(tempKey);
            StringBuilder testPword3 = MGLPasswordHash.EncryptPassword(tempKey2);

            bool theSame3 = MGLPasswordHash.Compare(tempKey, testPword2);
            bool theSame4 = MGLPasswordHash.Compare(tempKey, testPword3);

            success = theSame3 == true && theSame4 == false;

            return(success);
        }
Exemple #5
0
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        ///     Encrypts the given string
        /// </summary>
        public static StringBuilder EncryptPassword(StringBuilder password)
        {
            StringBuilder encryptedPassword = null;

            try {
                // First we need to turn the input string into a byte array.
                // 5-Jul-15 - by adding a random padding of 8 chars at the start, we ensure that a password of "Hello World" will not be
                // the same twice when encrypted
                StringBuilder randomPaddingSalt = MGLEncryption.GetSalt(SaltLength);

                // Turn the password into Key and IV.  We are using salt to make it harder to guess our key
                // using a dictionary attack - trying to guess a password by enumerating all possible words.
                // and generate a password specific salt that we will append to the end of the string ...
                StringBuilder randomAlgSaltStr = MGLEncryption.GetSalt(SaltLength);

                encryptedPassword = Encrypt(password, randomPaddingSalt.ToString(), randomAlgSaltStr.ToString(), SaltIterations);
            } catch (Exception ex) {
                Logger.LogError(9, "Error trying to encrypt a password. " + ex.StackTrace);
            }

            return(encryptedPassword);
        }
 //---------------------------------------------------------------------------------------------------------------------------------------------------------
 /// <summary>
 ///     Compares the two secure strings and returns true if they are equivalent textually, both null or both empty
 ///     if isCaseSensitive == true, we also compare the case sensitivity of the information - but this needs a string comparison
 ///     so will result in strings popping into memory and is probably a little bit slower ...
 /// </summary>
 public static bool AreEqual(SecureString ss1, SecureString ss2, bool isCaseSensitive)
 {
     return(MGLEncryption.AreEqual(SecureStringWrapper.Decrypt(ss1), SecureStringWrapper.Decrypt(ss2), isCaseSensitive));
 }