簡體   English   中英

如何加密ASP.NET MVC中的URL?

[英]How do I encrypt URLs in ASP.NET MVC?

我需要在ASP.NET MVC應用程序中加密URL。

我是否需要在Route Collection中的Global頁面中編寫代碼以加密所有URL?

加密URL是個壞主意。 期。

你可能想知道我為什么這么說。

我為一家加密其URL的公司申請了一份申請。 這是一個webforms應用程序。 僅從URL中,幾乎不可能分辨出我要引起該問題的代碼部分。 由於調用webform控件的動態特性,您只需知道軟件將要發生的路徑。 這讓人非常不安。

除此之外,應用程序中沒有基於角色的授權。 這一切都基於加密的URL。 如果你可以解密URL(如果它可以被加密,它可以被解密),那么你可以想象輸入另一個加密的URL並冒充另一個用戶。 我不是說這很簡單,但可能會發生。

最后,您多久使用一次互聯網並查看加密的URL? 當你這樣做的時候,你內心有點死嗎? 我做。 URL旨在傳達公共信息。 如果您不希望它這樣做,請不要將其放在您的URL中(或者需要對您站點的敏感區域進行授權)。

您在數據庫中使用的ID應該是可供用戶查看的ID。 如果您使用SSN作為主鍵,則應更改Web應用程序的架構。

任何可以加密的東西都可以被解密,因此容易受到攻擊。

如果您希望用戶只有在獲得授權的情況下才能訪問某些URL,那么您應該使用ASP.NET MVC中提供的[Authorize]屬性。

加密整個網址,我同意,非常糟糕的主意。 加密網址參數? 不是那么多,實際上是一種有效且廣泛使用的技術。

如果你真的想要加密/解密url參數(這根本不是一個壞主意),那么請查看Mads Kristensen的文章“ 用於查詢字符串加密的HttpModule ”。

您需要修改context_BeginRequest以使其適用於MVC。 只需刪除if語句的第一部分,檢查原始URL是否包含“aspx”。

話雖如此,我已經在幾個項目中使用過這個模塊(如果需要的話,還有一個轉換后的VB版本),並且在大多數情況下,它就像一個魅力。

但是,在某些情況下,我遇到了一些jQuery / Ajax調用無法正常工作的問題。 我確信可以修改模塊以補償這些情況。

基於這里的答案,這對我來說不起作用BTW,我找到了另一種基於我特定的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文件夾中,而不是 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 Init方法

C#請在類型名稱中明確指定程序集

https://stackoverflow.com/questions/1391060/httpmodule-with-asp-net-mvc-not-被叫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM