Url参数的安全性处理
前几天朋友问我了一个关于Url参数安全性的问题,之前由于做的大多是内部网站,安全性方面几乎是没有涉及到,很多时候就直接将Url中的参数名和参数值直接暴露给了客户端,确实存在很严重的安全隐患。
对于Url参数的处理主要的方法包括了加密参数串,使用Post方法。
比较常用的加密方法是采用Base64的方式对字符串进行加密:
View Code1 /// <summary> 2 /// Base64编码方式 3 /// </summary> 4 public class Base64 5 { 6 /// <summary> 7 /// 加密 8 /// </summary> 9 /// <param name="str">明文(UTF-8)</param> 10 /// <returns>密文</returns> 11 public static string Encode(string plainText) 12 { 13 return Encode(plainText, "UTF-8"); 14 } 15 16 /// <summary> 17 /// 加密 18 /// </summary> 19 /// <param name="plainText">明文</param> 20 /// <param name="name">编码名称</param> 21 /// <returns>密文</returns> 22 public static string Encode(string plainText, string name) 23 { 24 byte[] bt = Encoding.GetEncoding(name).GetBytes(plainText); 25 return Convert.ToBase64String(bt); 26 } 27 28 /// <summary> 29 /// 解密 30 /// </summary> 31 /// <param name="cipherText">密文(UTF-8)</param> 32 /// <returns>明文</returns> 33 public static string Decode(string cipherText) 34 { 35 return Decode(cipherText, "UTF-8"); 36 } 37 38 /// <summary> 39 /// 解密 40 /// </summary> 41 /// <param name="cipherText">密文</param> 42 /// <param name="name">编码名称</param> 43 /// <returns>明文</returns> 44 public static string Decode(string cipherText, string name) 45 { 46 byte[] bt = Convert.FromBase64String(cipherText); 47 return Encoding.GetEncoding(name).GetString(bt); 48 } 49 }日常使用中,如Url为http://localhost/web?arg1=1&arg2=2,这样的形式,加密后一般会同意存为http://localhost/web?args=YXJnMT0xJmFyZzI9Mg==这样的形式。当然除了采用Base64加密方法以为还可以采用其他的加密方式进行处理,原理相同。
在.net中直接使用Post方法存在较多限制,需要对web.config和页面进行一些设置:
web.config中需要进行如下配置:<machineKey validationKey="AutoGenerate|value[,IsolateApps]" decryptionKey="AutoGenerate|value[,IsolateApps]" validation="[SHA1|MD5|3DES]" decryption="[Auto|]" />关于machineKey,MSDN是如下描述的:
“对密钥进行配置,以便将其用于对 Forms 身份验证 Cookie 数据和视图状态数据进行加密和解密,并将其用于对进程外会话状态标识进行验证。”
具体内容点击传送门。
创建validationKey与decryptionKey的方法我们可以使用RNGCryptoServiceProvider所提供的方法进行生成,也可使用我提供的方法进行生成,key的长度根据validation进行选择:
View Codeprotected string CreateKey(int len) { byte[] bytes = new byte[len]; new RNGCryptoServiceProvider().GetBytes(bytes); StringBuilder sb = new StringBuilder(); for(int i = 0; i < bytes.Length; i++) { sb.Append(string.Format("{0:X2}",bytes[i])); } return sb.ToString(); }
附带可用配置一个:
View Code<system.web> <compilation debug="true" targetFramework="4.0" /> <machineKey validation="3DES" validationKey="3B65AC4F524714843D27DCD88D726E84BDDCB218EEEDA563B3A37BCF18624AA388502009F3059504AD1DFF72171C165C" decryption="3DES" decryptionKey="DBDF6B73DD4C1EB68783B8913D6969E247B459A1F1C6E8678BB48F1AB74BE03E35014EFCABA5346AB4EEF062DAD79D26" /> </system.web>
除此之外还需要在页面的Page引用中添加ViewStateEncryptionMode和EnableViewStatMac这两个属性:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" ViewStateEncryptionMode="Never" EnableViewStateMac="false" %>
页面才能进行Post方法的使用。