-2

I ported my .net webapi to .net core webapi. In my old code I was using

Cryptographer.CreateHash("SHA1CryptoServiceProvider", strPass);

For this I was using library Microsoft.Practices.EnterpriseLibrary.Security.Cryptography

But after porting to .net core I am facing issue:

{System.MissingMethodException: Method not found: 'System.AppDomainSetup System.AppDomain.get_SetupInformation()'.
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource.SafeGetCurrentConfigurationFile()
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceFactory.Create()
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.SetCurrentContainerIfNotSet()
   at Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.GetHashProvider(String hashInstance)
   at Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.CreateHash(String hashInstance, String plaintext)
   at Social27Bot.DAL.Data.Mappers.Security.EncryptPass(String strPass) 

What is the solution for this?

Jamie Taylor
  • 1,644
  • 1
  • 18
  • 42
Dalvir Singh
  • 423
  • 3
  • 11
  • 25
  • AS you are using SHA41 to hash the strings, I feel like this question is a partial duplicate of [Using SHA-1 in .NET Core](https://stackoverflow.com/questions/40740894/using-sha-1-in-net-core) – Jamie Taylor Jul 05 '19 at 10:36
  • Possible duplicate of [Using SHA-1 in .NET Core](https://stackoverflow.com/questions/40740894/using-sha-1-in-net-core) – Jamie Taylor Jul 05 '19 at 10:37
  • Do you have an appname.config file in your app? Might be related to [a config file problem](https://github.com/Chavoshi/EnterpriseLibrary.NetCore/issues/28) – mvila Jul 05 '19 at 11:00
  • 2
    *Don't* use `Microsoft.Practices.EnterpriseLibrary`. It's a legacy library created over a decade ago to handle scenarios that are now handled by .NET itself. It's definitely *not* meant to work with Core. – Panagiotis Kanavos Jul 05 '19 at 11:34
  • Besides, **SHA1 is obsolete and considered compromised for password hashing** for years. It's far too easy to break. It shouldn't be used under any circumstances, especially not for code targeting new runtimes. Again, secure cryptographic hashing of passwords is *already* available in .NET through the [Rfc2898DeriveBytes](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes?view=netframework-4.8) class. – Panagiotis Kanavos Jul 05 '19 at 11:38
  • Finally, ASP.NET Core's Identity already provides strong cryptographic hashing and storage of passwords. There's no reason to build your own. You can check the source code to see how it works though, eg the [HashPasswordv3](https://github.com/aspnet/AspNetCore/blob/f35564ba0635da588214791b3662085bd30d243e/src/Identity/Extensions.Core/src/PasswordHasher.cs#L141) method uses ASP.NET Core's [KeyDerivation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.cryptography.keyderivation.keyderivation?view=aspnetcore-2.2) class – Panagiotis Kanavos Jul 05 '19 at 11:46
  • @PanagiotisKanavos, he is porting an app and although your comments are true maybe he needs to keep using [EnterpriseLibrary](https://github.com/Chavoshi/EnterpriseLibrary.NetCore) and SHA1 for some reason – mvila Jul 05 '19 at 11:55
  • @mvila moving to .NET Core isn't a simple port, especially when working with legacy libraries. The very top line of the error shows what's wrong. EntLib is trying to use a method that [no longer exists](https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.setupinformation?view=netframework-4.8&viewFallbackFrom=netcore-2.2). It will become available again in .NET Core 3. As for SHA1 and "some reason", there's every reason to *not* use SHA1, including legal and insurance. Even with SHA1, secure implementations exist in .NET itself. `Rfc2898DeriveBytes` uses salting & 1000 hash iterations – Panagiotis Kanavos Jul 05 '19 at 12:10
  • @PanagiotisKanavos I agree 100% about not using SHA1, but seems as their current app is using SHA1, and the same reasons apply for not using it in .Net Framework and they didn't change it. About EntLib, some old projects rely heavily on it, and it's being ported to .Net Standard. I just understood the question as "how can I port using this" instead of "how should I port this". – mvila Jul 05 '19 at 13:42

2 Answers2

1

Long story short, EntLib is a legacy library created over a decade ago. Don't use it. It was never meant to be used in .NET Core and obviously, never upgraded to work with it. Use KeyDerivation.Pbkdf2 instead.

In this specific case you can't use EntLib at all because it tries to use a non-existent property, AppDomain.SetupInformation. The AppDomain class was removed in the first versions of .NET Core and added back i .NET Core 2.0. Even now, it doesn't offer all members, including SetupInformation.

As the documentation page explains, this property will be added back in .NET Core 3.0, due to be released in September.

The real solution is to not use such code in the first place, and use ASP.NET Core's Identity to store passwords.

Hashing a password with SHA1 like this is trivial to break in minutes if not less. Way back when people used to create rainbow tables, pre-calculated SHA1 hashes for all password combinations and just lookup a hash to find the password. Nowadays, it's probably faster to just brute-force it than search a big table of hashes.

ASP.NET always provided far more secure password hashing and storage that included salting and multiple hash iterations. In ASP.NET Web Forms and older versions of MVC, salting and at least 1000 hash iterations were used.

ASP.NET Core Identity also offers secure hashing and storage. Using it is the easiest and most secure option. It's open source, so even if one can't use it, it's easy to check how it hashes passwords.

The HashPasswordV3 method uses ASP.NET Core's KeyDerivation class to hash a user-supplied password. The code is very simple. Essentially, it's a call to KeyDerivation.Pbkdf2 with a 16-byte salt that returns a 32-byte hash buffer.

byte[] salt = new byte[16];
rng.GetBytes(salt);
byte[] subkey = KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA256, 
                                     iterCount, 32);

The rest of the code packs the hash algorithm ID, hash bytes, iteration count and salt in a single byte array for storage in a table. Those attributes could be stored in different columns in the table, but putting everything in a single byte[] array is more convenient.

The VerifyHashedPasswordV3 later on reads the stored buffer, extracts the attributes and hashes the provided password before checking the stored and calculated hashes

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
-3

Try this,

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DevExtremeAspNetCoreApp07052019.App_Start;


namespace DevExtremeAspNetCoreApp07052019.App_Start
{
    public class HelperClass
    {

        public static char Mid(string param, int startIndex, int length)
        {
            Char result = Convert.ToChar(param.Substring(startIndex, length));
            return result;
        }
        public static string Decrypt(string icText)
        {
            int icLen;
            string icNewText = "";
            char icChar;
            //icChar = '' ;
            icLen = icText.Length;
            for (int i = 0; i <= icLen-1; i++)
            {
                icChar = Mid(icText, i, 1);
                switch (Strings.AscW(icChar))
                {
                    case object _ when 192 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 217:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) - 127);
                            break;
                        }

                    case object _ when 218 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 243:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) - 121);
                            break;
                        }

                    case object _ when 244 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 253:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) - 196);
                            break;
                        }

                    case 32:
                        {
                            icChar = Strings.ChrW(32);
                            break;
                        }
                }
                icNewText = icNewText + icChar;
            }
           // icNewText = Microsoft.VisualBasic.StrReverse(icNewText);
            return (icNewText);
        }
        public static string Encrypt(string icText)
        {
            int icLen;
            string icNewText = "";
            char icChar;
            icLen = icText.Length;
            for (int i = 1; i <= icLen; i++)
            {
                icChar = Mid(icText, i, 1); 
                switch (Strings.AscW(icChar))
                {
                    case object _ when 65 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 90:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) + 127);
                            break;
                        }

                    case object _ when 97 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 122:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) + 121);
                            break;
                        }

                    case object _ when 48 <= Strings.AscW(icChar) && Strings.AscW(icChar) <= 57:
                        {
                            icChar = Strings.ChrW(Strings.AscW(icChar) + 196);
                            break;
                        }

                    case 32:
                        {
                            icChar = Strings.ChrW(32);
                            break;
                        }
                }
                icNewText = icNewText + icChar;
            }
            return (icNewText);
        }

        public static string ReplaceFirstOccurrence(string Source, string Find, string Replace)
        {
            string result = "";
            int Place = Source.IndexOf(Find);
            if (Place != -1)
            {
                result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
            }
            else
            {
                result = Source;
            }
            return result;
        }

        public static string SQLString(string sStrings, Boolean Trim = true)
        {
            //Get
            //{

            if (Trim)
            {
                if (sStrings != null && sStrings.Trim() != "")
                    return ReplaceFirstOccurrence(sStrings.Trim(), "'", "''");
                else
                    return "";
            }
            else if (sStrings.Trim() != "")
                return ReplaceFirstOccurrence(sStrings, "'", "''");
            else
                return "";
            //}
        }

    }
}
Prakash S
  • 85
  • 8