C# MVC 查询字符串编码和解码
Posted
技术标签:
【中文标题】C# MVC 查询字符串编码和解码【英文标题】:C# MVC Query String Encoding and Decoding 【发布时间】:2017-11-01 00:13:33 【问题描述】:我想对 url 参数进行编码和解码。
在javascript中调用函数
var url = '/Demo/Demo?id=58';
$(location).attr('href', url)
当前url参数
www.example.com/Demo/Demo?id=58
演示控制器中的代码
public ActionResult Demo(int id)
return view();
我希望上面的 url 像 bolow 行一样更改
www.example.com/Demo/Demo?id=Sff5f8ddg
这样 id 值将是机密的。编码和解码的最佳方式是什么。
注意:我们通过锚标记、ajax 和 jquery 调用方法。 Base64以外的编码和解码
除了Base64编码和解码之外,还有其他加密方法,如javascript中的加密和C#方法中的解密
【问题讨论】:
如果传递机密参数,则不使用查询字符串参数,但可以使用后参数 分享一些post参数的例子 你最喜欢的搜索引擎宕机了吗? 在 url 中编码查询字符串的最佳方式 这取决于 (a) 如果您只是想混淆您的参数或 (b) 保护您的参数。我会遵循@hazzik 所说的并使用 GUID。如果user N
存在问题,需要适当的权限才能访问该操作,那么您需要在服务器端使用传递的 ID 执行任何操作之前检查这一点。
【参考方案1】:
这样 id 值将是机密的。编码和解码的最佳方式是什么。
不会的。至少在你试图做到的方式上。一旦您对 [internal] id 进行编码,它就会成为该条目的公共 id。用户使用哪个 id 无关紧要:58
或 Sff5f8ddg
,因为它将引用系统中的相同条目。如果您使用的是无盐算法,它只会阻止不那么成熟的用户发现您系统中的其他条目。
据我了解,您要解决的问题是 - 如何通过为某些条目设置 id 来使其他条目无法被发现。例如,如果用户有条目 58 的 url,他们应该无法找到条目 57 和 59。
解决方案是:使用 GUID 作为条目的 ID。
此外,您需要确保已为您的条目实施了适当的访问控制。
【讨论】:
由于 GUID 与 ID 相关联并且任何人都可以识别 GUID,因此检测到所有可用的 GUID 只是时间问题。 @RuardvanElburg 对不起,WAT?祝你好运...the number of random version 4 UUIDs which need to be generated in order to have a 50% probability of at least one collision is 2.71 quintillion [...] This number is equivalent to generating 1 billion UUIDs per second for about 85 years
。我可以得到你的许可打印你的评论并贴在我的墙上吗?
另外,为什么我什至需要将 GUID 链接到任意整数 ID?【参考方案2】:
在javascript中,你可以使用
var str = "Hello World!";
var enc = window.btoa(str);
var dec = window.atob(enc);
res 的结果是:
Encoded String: SGVsbG8gV29ybGQh
Decoded String: Hello World!
这个例子展示了如何使用 RijndaelManaged 进行加密解密。
public static class Cryptography
private static readonly byte[] _key = 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03 ;
private static readonly byte[] _iV = 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13 ;
#region Encryption
public static string Encrypt(this string inputText)
string _encryptString = string.Empty;
if (string.IsNullOrEmpty(inputText))
return string.Empty;
else
ASCIIEncoding textConverter = new ASCIIEncoding();
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform encryptor = myRijndael.CreateEncryptor(_key, _iV);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
byte[] toEncrypt = textConverter.GetBytes(inputText);
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();
_encryptString = Convert.ToBase64String(msEncrypt.ToArray()).Replace(" ", "+");
return _encryptString;
public static string Decrypt(this string inputText)
string text = inputText;
try
if (string.IsNullOrEmpty(inputText))
return string.Empty;
else
inputText = inputText.Replace(" ", "+");
byte[] encrypted = Convert.FromBase64String(inputText);
ASCIIEncoding textConverter = new ASCIIEncoding();
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform decryptor = myRijndael.CreateDecryptor(_key, _iV);
MemoryStream msDecrypt = new MemoryStream(encrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
byte[] fromEncrypt = new byte[encrypted.Length];
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return textConverter.GetString(fromEncrypt).TrimEnd('\x0');
catch (FormatException)
return "";
catch (Exception ex)
return text;
#endregion Encryption
现在在控制器中加密解密就像
"id".Encrypt();///
"encryptID".Decrypt();
【讨论】:
你可以分享javascript和控制器方法的示例代码 RijndaelManaged myRijndael = new RijndaelManaged();显示错误 您需要添加命名空间“使用 System.Security.Cryptography” 方法 -> public ActionResult Demo(int id)。那么 int 数据类型将返回错误 您必须将 int 值转换为字符串,如 "58".Encrypt()【参考方案3】:var id=Encrypt(YourID);
var id=Decrypt(YourID);
using System.Security.Cryptography;
public static string Encrypt(string inputText)
string encryptionkey = "SAUW193BX628TD57";
byte[] keybytes = Encoding.ASCII.GetBytes(encryptionkey.Length.ToString());
RijndaelManaged rijndaelCipher = new RijndaelManaged();
byte[] plainText = Encoding.Unicode.GetBytes(inputText);
PasswordDeriveBytes pwdbytes = new PasswordDeriveBytes(encryptionkey, keybytes);
using (ICryptoTransform encryptrans = rijndaelCipher.CreateEncryptor(pwdbytes.GetBytes(32), pwdbytes.GetBytes(16)))
using (MemoryStream mstrm = new MemoryStream())
using (CryptoStream cryptstm = new CryptoStream(mstrm, encryptrans, CryptoStreamMode.Write))
cryptstm.Write(plainText, 0, plainText.Length);
cryptstm.Close();
return Convert.ToBase64String(mstrm.ToArray());
public static string Decrypt(string encryptText)
string encryptionkey = "SAUW193BX628TD57";
byte[] keybytes = Encoding.ASCII.GetBytes(encryptionkey.Length.ToString());
RijndaelManaged rijndaelCipher = new RijndaelManaged();
byte[] encryptedData = Convert.FromBase64String(encryptText.Replace(" ", "+"));
PasswordDeriveBytes pwdbytes = new PasswordDeriveBytes(encryptionkey, keybytes);
using (ICryptoTransform decryptrans = rijndaelCipher.CreateDecryptor(pwdbytes.GetBytes(32), pwdbytes.GetBytes(16)))
using (MemoryStream mstrm = new MemoryStream(encryptedData))
using (CryptoStream cryptstm = new CryptoStream(mstrm, decryptrans, CryptoStreamMode.Read))
byte[] plainText = new byte[encryptedData.Length];
int decryptedCount = cryptstm.Read(plainText, 0, plainText.Length);
return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
【讨论】:
【参考方案4】:从您的问题中我可以理解的是,您希望限制用户能够知道 id 参数的确切值。
但这无济于事,因为您的浏览器/客户端已经拥有该值。 所以你在你的客户上有 id 并且你想限制你的客户知道它的价值。 普通开发人员(任何编写代码的人)都可以使用浏览器的开发人员工具访问您的价值。 所以没有任何好处。
另一种方法是您从服务器本身发送加密的 id。 为此,您可以使用@Karan Singh 提供的解决方案。 或者您想要探索的任何其他选项都取决于您。
一个建议尝试使用一种无法反向完成的加密方法。这将增加处理开销,因为您必须首先从 DB 加密您的 Id,然后将其与客户端发送的值匹配。
谢谢。
【讨论】:
【参考方案5】:您可以简单地使用 jquery 函数,例如:
var encodedUrl = encodeURIComponent("your url"); //'/Demo/Demo?id=58';
console.log(encodedUrl);
谢谢
【讨论】:
它正在返回“'/' 应用程序中的服务器错误。”点击时 我得到了一个完美的结果,例如:%2FDemo%2FDemo%3Fid%3D58 id 58 可见【参考方案6】:如果您要做的是从呈现的内容(客户端)中隐藏 58,那么您需要在后端实现加密/解密方案并根据需要将该值从/传递到客户端.
当您向客户端提供数据时,您的服务器端代码会将 58 加密为一些字符串,以隐藏真实值并将其传递给客户端。
当客户端向您发出请求时,它应该使用您之前提供的加密字符串,并且您的服务器应该将其解密成它可以使用的东西。
您不需要 JavaScript 来加密和 C# 来解密这些值。 JavaScript 部分应该始终使用加密的 id,因为它是在客户端执行 事后 的脚本。服务器端如何使用该值是客户端 JavaScript 不需要了解的内部方面。
【讨论】:
【参考方案7】:你好,我想你想创建一个脾气暴躁的查询字符串Download the code from github repository
【讨论】:
【参考方案8】:控制器:
[HttpPost]
public ActionResult SubmitInputTest(int id)
//your code
//do stuff
return RedirectToAction("index");
在你看来(cshtml):
<form id="frmToSubmit" action="<controller>/SubmitInputTest">
<hidden id="id" name="id"/>
</form>
在你的 javascript 中:
$('#id').attr('value', [your ID Value]);
$('#frmToSubmit').submit();
【讨论】:
它不是一种形式。只是 标签 你在哪里指定要使用标签???如果你执行一个 javascript 函数,你可以按需创建一个表单并发布它 我不会使用表单以上是关于C# MVC 查询字符串编码和解码的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 java 对从 javascript 到 servletpage 的查询字符串进行编码和解码?