Как зашифровать URL-адреса в ASP.NET MVC? - PullRequest
3 голосов
/ 16 декабря 2010

Мне нужно зашифровать URL-адреса в моем приложении ASP.NET MVC.

Нужно ли писать код на глобальной странице в коллекции маршрутов для шифрования всех URL-адресов?

Ответы [ 3 ]

7 голосов
/ 17 декабря 2010

Это плохая идея, чтобы зашифровать URL. Период.

Вы можете удивиться, почему я так говорю.

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

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

Наконец, как часто вы используете Интернет и видите зашифрованные URL-адреса? Когда ты умрешь, ты умрешь немного внутри? Я делаю. URL предназначены для передачи публичной информации. Если вы не хотите, чтобы это делалось, не указывайте это в своем URL-адресе (или не требуйте авторизацию для чувствительных областей вашего сайта).

Идентификаторы, которые вы используете в базе данных, должны быть идентификаторами, которые могут быть просмотрены пользователем. Если вы используете SSN в качестве первичного ключа, вам следует изменить эту схему для веб-приложения.

Все, что может быть зашифровано, может быть расшифровано и, следовательно, уязвимо для атаки.

Если вы хотите, чтобы пользователь имел доступ только к определенным URL-адресам, если он авторизован, вам следует использовать атрибуты [Authorize], доступные в ASP.NET MVC.

4 голосов
/ 04 апреля 2012

Шифрование всего URL, я согласен, очень плохая идея. Шифрование параметров URL? Не так много, и на самом деле является действительным и широко используемым методом.

Если вы действительно хотите зашифровать / расшифровать параметры URL (что вовсе не является плохой идеей), прочитайте статью Мэдса Кристенсена " HttpModule для шифрования строки запроса ".

Вам нужно будет изменить context_BeginRequest, чтобы заставить его работать для MVC. Просто удалите первую часть оператора if, которая проверяет, содержит ли исходный URL «aspx».

С учетом вышесказанного, я использовал этот модуль в нескольких проектах (при необходимости имею конвертированную версию VB) и по большей части он работает как шарм.

НО, есть некоторые случаи, когда у меня возникали некоторые проблемы с некорректной работой вызовов jQuery / Ajax. Я уверен, что модуль можно изменить, чтобы компенсировать эти сценарии.

1 голос
/ 05 октября 2017

Основываясь на ответах, которые здесь не сработали, кстати, я нашел другое решение , основанное на моей конкретной реализации MVC, и тот факт, что оно также работает в зависимости от того, используете ли вы II7 или II6. Небольшие изменения необходимы в обоих случаях.

II6

Во-первых, вам нужно добавить следующее в web.config (root, а не тот, что в папке View).

 <system.web>
    <httpModules>
      <add name="URIHandler" type="URIHandler" />
    </httpModules>

II7

вместо этого добавьте это в ваш web.config (root, а не тот, который находится в папке View).

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="URIHandler" />
      <add name="URIHandler" type="URIHandler" />
    </modules>

Или вы можете добавить оба. На самом деле это не имеет значения.

Далее используйте этот класс. Я назвал это, как вы, наверное, заметили - URIHandler .

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

public class URIHandler : IHttpModule
    {
        #region IHttpModule members
        public void Dispose()
        {
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }
        #endregion

        private const string PARAMETER_NAME = "enc=";
        private const string ENCRYPTION_KEY = "key";

        private void context_BeginRequest(object sender, EventArgs e)
        {
            HttpContext context = HttpContext.Current;
            //if (context.Request.Url.OriginalString.Contains("aspx") && context.Request.RawUrl.Contains("?"))
            if (context.Request.RawUrl.Contains("?"))
            {
                string query = ExtractQuery(context.Request.RawUrl);
                string path = GetVirtualPath();

                if (query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase))
                {
                    // Decrypts the query string and rewrites the path.
                    string rawQuery = query.Replace(PARAMETER_NAME, string.Empty);
                    string decryptedQuery = Decrypt(rawQuery);
                    context.RewritePath(path, string.Empty, decryptedQuery);
                }
                else if (context.Request.HttpMethod == "GET")
                {
                    // Encrypt the query string and redirects to the encrypted URL.
                    // Remove if you don't want all query strings to be encrypted automatically.
                    string encryptedQuery = Encrypt(query);
                    context.Response.Redirect(path + encryptedQuery);
                }
            }
        }

        /// <summary>
        /// Parses the current URL and extracts the virtual path without query string.
        /// </summary>
        /// <returns>The virtual path of the current URL.</returns>
        private static string GetVirtualPath()
        {
            string path = HttpContext.Current.Request.RawUrl;
            path = path.Substring(0, path.IndexOf("?"));
            path = path.Substring(path.LastIndexOf("/") + 1);
            return path;
        }

        /// <summary>
        /// Parses a URL and returns the query string.
        /// </summary>
        /// <param name="url">The URL to parse.</param>
        /// <returns>The query string without the question mark.</returns>
        private static string ExtractQuery(string url)
        {
            int index = url.IndexOf("?") + 1;
            return url.Substring(index);
        }

        #region Encryption/decryption

        /// <summary>
        /// The salt value used to strengthen the encryption.
        /// </summary>
        private readonly static byte[] SALT = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString());

        /// <summary>
        /// Encrypts any string using the Rijndael algorithm.
        /// </summary>
        /// <param name="inputText">The string to encrypt.</param>
        /// <returns>A Base64 encrypted string.</returns>
        [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        public static string Encrypt(string inputText)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            byte[] plainText = Encoding.Unicode.GetBytes(inputText);
            PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, SALT);

            using (ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16)))
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(plainText, 0, plainText.Length);
                        cryptoStream.FlushFinalBlock();
                        return "?" + PARAMETER_NAME + Convert.ToBase64String(memoryStream.ToArray());
                    }
                }
            }
        }

        /// <summary>
        /// Decrypts a previously encrypted string.
        /// </summary>
        /// <param name="inputText">The encrypted string to decrypt.</param>
        /// <returns>A decrypted string.</returns>
        [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        public static string Decrypt(string inputText)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            byte[] encryptedData = Convert.FromBase64String(inputText);
            PasswordDeriveBytes secretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, SALT);

            using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
            {
                using (MemoryStream memoryStream = new MemoryStream(encryptedData))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] plainText = new byte[encryptedData.Length];
                        int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
                        return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
                    }
                }
            }
        }
        #endregion
    }

Вам не нужно NameSpace.

Приведенный выше класс делает все необходимое для шифрования и дешифрования любых параметров URL, начиная с символа '?'. Он даже делает хорошую работу по переименованию переменных вашего параметра в «enc», что является бонусом.

Наконец, поместите класс в папку App_Start и NOT App_Code, поскольку это будет конфликтовать с «однозначными ошибками».

Готово.

Кредиты:

https://www.codeproject.com/questions/1036066/how-to-hide-url-parameter-asp-net-mvc

https://msdn.microsoft.com/en-us/library/aa719858(v=vs.71).aspx

Метод инициализации HttpModule не был вызван

C # Пожалуйста, укажите сборку явно в имени типа

https://stackoverflow.com/questions/1391060/httpmodule-with-asp-net-mvc-not- будучи называемой

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...