Специальные символы в шифровании MD5 - PullRequest
0 голосов
/ 04 сентября 2018

У меня проблема с шифрованием MD5 в C # и SQL Server, это происходит только в строках со специальными символами.

Вот код в c #:

public virtual string RowHash<T>(T item)
    {
        PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var finalvalue = "";
        foreach (PropertyInfo p in properties)
        {
            if (p.Name != "Hash")
            {
                if (!p.CanWrite || !p.CanRead) { continue; }

                MethodInfo mget = p.GetGetMethod(false);
                MethodInfo mset = p.GetSetMethod(false);

                // Get and set methods have to be public
                if (mget == null) { continue; }
                if (mset == null) { continue; }
                var value = p.GetValue(item, null) == null ? "" : p.GetValue(item, null) is Entity? ((Entity)p.GetValue(item, null)).Id.ToString() : p.GetValue(item, null).ToString();
                finalvalue += value;
            }

        }
        return finalvalue;
    }

    public static string GetMD5(string text)
    {
        var md5 = MD5CryptoServiceProvider.Create();
        var encoding = new ASCIIEncoding();
        byte[] stream = null;

        var sb = new StringBuilder();
        stream = md5.ComputeHash(encoding.GetBytes(text));

        for (int i = 0; i < stream.Length; i++) sb.AppendFormat("{0:x2}", stream[i]);

        return sb.ToString();
    }

    public static string PasswordMD5(string password)
    {
        var pwd = GetMD5(password + GetMD5(password).Substring(0,2));
        return pwd;
    }

С помощью метода RowHash я получаю конкатенацию всех полей из строки, если только хэш поля, в котором будет сохранен результат, затем отправил его методу PasswordMD5, который создает зашифрованный хэш, который мы сохраняем в базе данных.

Затем я делаю то же самое в SQL Server с этим кодом:

CONVERT(VARCHAR(32), HashBytes('MD5',CONVERT(VARCHAR(MAX),CONVERT(VARCHAR(MAX),ISNULL([Field1],''))+ISNULL([Field2],'')+ISNULL([Field3],'')+CONVERT(VARCHAR(MAX),ISNULL([Field4],''))+ISNULL(CONVERT(VARCHAR(MAX),[Field5]),'')+ISNULL(CONVERT(VARCHAR(MAX),Field6]),'')+CONVERT(VARCHAR(MAX),Field7]))+SUBSTRING(CONVERT(VARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR(MAX),CONVERT(VARCHAR(MAX),ISNULL([Field1],''))+ISNULL([Field2],'')+ISNULL([Field3],'')+CONVERT(VARCHAR(MAX),ISNULL([Field4],''))+ISNULL(CONVERT(VARCHAR(MAX),Field5]),'')+ISNULL(CONVERT(VARCHAR(MAX),[Field6]),'')+CONVERT(VARCHAR(MAX),Field7]))) 2), 1, )), 2)

Затем я сравниваю это с хэшем, который я создал в C #, чтобы проверить целостность данных, которые у меня есть в базе данных. Это прекрасно работает для всех строк без специальных символов, но не для всех строк, которые содержат специальные символы, такие как é или ö.

Это проблема, с которой я столкнулся некоторое время назад, но задача была приостановлена ​​другими приоритетами, я не помню точно, какие решения я уже пробовал, я помню, что я пробовал некоторые решения, меняющие кодировку строк в C #, но никто не работал.

Что я делаю не так?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Наконец, я не могу найти хорошее решение с использованием MD5, я перешел на SHA256, и он работал, используя этот ответ:

https://stackoverflow.com/a/19214122/4890862

0 голосов
/ 04 сентября 2018

Я использую этот метод шифрования и дешифрования для своего кода, и я уже проверил со специальным символом, и он отлично работает для меня. Я пришлю вам мой код, пожалуйста, проверьте это, как только я надеюсь, что это сработает.

TableFilter - это файл общего класса, файл которого содержит метод шифрования и дешифрования. Ничего другого вы не можете написать этим двум методам на странице .cs.

public static string Encrypt(string toEncrypt, bool useHashing = true)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

        System.Configuration.AppSettingsReader settingsReader =
                                            new AppSettingsReader();
        // Get the key from config file

        string key = (string)settingsReader.GetValue("EncryptionKey",
                                                         typeof(String));
        //System.Windows.Forms.MessageBox.Show(key);
        //If hashing use get hashcode regards to your key
        if (useHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //Always release the resources and flush data
            // of the Cryptographic service provide. Best Practice

            hashmd5.Clear();
        }
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(key);

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)
        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)

        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        //transform the specified region of bytes array to resultArray
        byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0,
          toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        //Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    public static string Decrypt(string cipherString, bool useHashing = true)
    {
        byte[] keyArray;
        //get the byte code of the string

        byte[] toEncryptArray = Convert.FromBase64String(cipherString);

        System.Configuration.AppSettingsReader settingsReader =
                                            new AppSettingsReader();
        //Get your key from config file to open the lock!
        string key = (string)settingsReader.GetValue("EncryptionKey",
                                                     typeof(String));

        if (useHashing)
        {
            //if hashing was used get the hash code with regards to your key
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //release any resource held by the MD5CryptoServiceProvider

            hashmd5.Clear();
        }
        else
        {
            //if hashing was not implemented get the byte code of the key
            keyArray = UTF8Encoding.UTF8.GetBytes(key);
        }

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes. 
        //We choose ECB(Electronic code Book)

        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)
        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(
                             toEncryptArray, 0, toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor                
        tdes.Clear();
        //return the Clear decrypted TEXT
        return UTF8Encoding.UTF8.GetString(resultArray);
    }

: для строки текстового поля (вместо txtpassword.text поставить тестирование123 для понимания))

login_Model.Password = TableFilter.Encrypt("testingé123ö");

: Web.config


    <add key="EncryptionKey" value="encyptionkeyvalue"/>
...