Thursday, January 27, 2005

 

Some notes on IE and cookie

1.
使用代码解析ViewSate的Base64值
From http://pierce.cnblogs.com/archive/2005/08/01/204725.html

ViewState的值的编码是Base64,默认状况下,是没有加密的,很容易读出。
ViewState的值可以加密,首先,确保Page的EnableViewStatMac=true,然后在Machine.Config中配置machineKey。
默认Machine.Config中的machineKey:
!-- validation="[SHA1|MD5|3DES]" -->
machineKey
validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"
validation="SHA1" />
可以修改machineKey来使用某种加密方式,注意:加密由Machine Layer完成,要消耗系统资源。本人关于加密ViewState没有测试。

通过使用浏览器,可以获取ViewState的隐藏内容,使用下面的代码,可以解析:
private string Base2String(string message)
{
byte[] by=System.Convert.FromBase64String(message);

string dest=System.Text.Encoding.ASCII.GetString(by);
return dest;

}
//如果ViewState的值为"dDw5NDA0MTAzOTY7dDxwPGw8cGFzczs+O2w8RmlzaDs
+Pjs7PjtsPF9jdGwwO2NoZWNrO19jdGwxO19jdGwyO19jdGwzO2NiOz4+";
string source="dDw5NDA0MTAzOTY7dDxwPGw8cGFzczs
+O2w8RmlzaDs
+Pjs7PjtsPF9jdGwwO2NoZWNrO19jdGwxO19jdGwyO19jdGwzO2NiOz4+";
Response.Write(Base2String(source));可以获得:t<940410396;t;l>;;>;l<_ctl0;check;_ctl1;_ctl2;_ctl3;cb;>>
其中,cb是指动态生成的CheckBox,共动态生成5个CheckBox,check是动态生成的第2个CheckBox的Id,其他的没有指定Id。

如果在Page的后台代码中完成上面的操作,需要重写SavePageStateToPersistenceMedium():
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// 调用基类的方法,完成基本操作
base.SavePageStateToPersistenceMedium(viewState);
// 获取ViewState的Base64值
LosFormatter format = new LosFormatter();
StringWriter writer = new StringWriter();
format.Serialize(writer, viewState);
string vsRaw = writer.ToString();
Response.Write("ViewState Raw: " + Server.HtmlEncode(vsRaw));
// 解析内容
byte[] buffer = Convert.FromBase64String(vsRaw);
string vsText = Encoding.ASCII.GetString(buffer);
Response.Write("ViewState Text: " + Server.HtmlEncode(vsText));
}
通过获取ViewState的值,可以有助于理解ViewState的目的和作用,毕竟ViewState中的StateBag,可以存储页面级的变量,通过PostBack发送,是非常有用的。


2.
使用混合脚本编程来实现的Base64编码
From http://www.cnblogs.com/birdshome/archive/2005/01/12/89185.html

在近来的工作中,需要在Web页上制作复杂的逻辑和框架以及后台之间交换数据,特别是和后台交换数据,编码是个必须考虑的问题。否则可能会因为编码不同,把脚本的执行给搞得乱七八糟,根本得不到想要的结果。Base64是一种常用而又简单的编码,就先从它下手弄弄了。

关于Base64的详细定义可以查看RFC 2045,如果简单的说一下呢:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)。好玩,弄来不被人识别?不识别就不识别嘛,反正程序能之别就行了。

http://www.faqs.org/rfcs/rfc2045.html

这个编码为什么叫Base64呢?这是应为它的转换需要依赖一张64个字符的转换表,叫做The Base64 Alphabet。 Base64以3个字节为一个转换单位,把这24bits分为4份,高位补零,再查前面说的那个转换表,就编码完毕了。如果被转换的数据(以byte为单位)不能被3整除,按余数补"="(pad),当然最多也就只有两种可能,不是补一个pad就是补两个pad。

例如转换"博客园",这三个字的内码十六进制为:B2A9 BFCD D4B0
二进制为:10110010 10101001 10111111 11001101 11010100 10110000
六个一拨:00101100 00101010 00100110 00111111 00110011 00011101 00010010 00110000,再按新的编码转为十进制查表后得到"博客园"的base64编码为:"sqm/zdSw"。
// 蓝色的0是补位的

之前有人用JavaScript来做过Base64编码,结果居然使用escape来获取字符的编码,这样当遇到被转换的字符有汉字时就faint掉了,escape在基于NT的32位系统下得到的是汉字的Unicode编码。但是JavaScript却真的没有办法得到汉字的GB码:( 我也郁闷了半天,后来在mozart0的帮助下使用VBScript加JScript混合搞定了这个编码算法实现。

http://www.unicode.org/

附1:The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 G 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

附2:base64编码源代码

script language="javascript">
var Base64Alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'];

function EncodeBase64(string)
{
var hexString = string.getGBCode();
window.status = hexString;
var base64 = '';
var B64A = Base64Alphabet;
var padCount = hexString.length%3;
var count = parseInt(hexString.length/6);
var i = 0;
for ( i=0 ; i < count ; ++i )
{
var intA = parseInt(hexString.charAt(i*6+0)+hexString.charAt(i*6+1), 16);
var intB = parseInt(hexString.charAt(i*6+2)+hexString.charAt(i*6+3), 16);
var intC = parseInt(hexString.charAt(i*6+4)+hexString.charAt(i*6+5), 16);
var part1 = intA >> 2;
var part2 = ((intA & 0x03) << 4) | (intB >> 4);
var part3 = ((intB & 0x0f) << 2) | (intC >> 6);
var part4 = intC & 0x3f;
base64 += B64A[part1] + B64A[part2] + B64A[part3] + B64A[part4];
}
if ( padCount == 1 )
{
var intA = parseInt(hexString.charAt(i*6+0)+hexString.charAt(i*6+1), 16);
var intB = parseInt(hexString.charAt(i*6+2)+hexString.charAt(i*6+3), 16);
var part1 = intA >> 2;
var part2 = ((intA & 0x03) << 4) | (intB >> 4);
var part3 = ((intB & 0x0f) << 2);
base64 += B64A[part1] + B64A[part2] + B64A[part3] + '=';
}
if ( padCount == 2 )
{
var intA = parseInt(hexString.charAt(i*6+0)+hexString.charAt(i*6+1), 16);
var part1 = intA >> 2;
var part2 = ((intA & 0x03) << 4);
base64 += B64A[part1] + B64A[part2] + '==';
}
return base64;
}
/script>
script language="vbscript">
function vbGetGBCode(str)
dim i, length, s
length = len(str)
for i=1 to length
hexCode = hex(asc(str.charAt(i-1)))
if (len(hexCode) mod 2) = 0 then
s = s & hexCode
else
s = s & "0" & hexCode
end if
next
vbGetGBCode = s
end function
/script>
script language="javascript">
String.prototype.getGBCode = function()
{
return vbGetGBCode(this);
}
/script>

3.
JavaScript实现的Base64编码和解码
From http://bbs.mscommunity.com/Forums/ShowThread.aspx?PostID=2349

script language=javascript>

var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

var base64DecodeChars = new Array(

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,

  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,

  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,

  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,

  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,

  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

function base64encode(str) {

  var out, i, len;

  var c1, c2, c3;

  len = str.length;

  i = 0;

  out = "";

  while(i < len) {

c1 = str.charCodeAt(i++) & 0xff;

if(i == len)

{

   out += base64EncodeChars.charAt(c1 >> 2);

   out += base64EncodeChars.charAt((c1 & 0x3) << 4);

   out += "==";

   break;

}

c2 = str.charCodeAt(i++);

if(i == len)

{

   out += base64EncodeChars.charAt(c1 >> 2);

   out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));

   out += base64EncodeChars.charAt((c2 & 0xF) << 2);

   out += "=";

   break;

}

c3 = str.charCodeAt(i++);

out += base64EncodeChars.charAt(c1 >> 2);

out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));

out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));

out += base64EncodeChars.charAt(c3 & 0x3F);

  }

  return out;

}

function base64decode(str) {

  var c1, c2, c3, c4;

  var i, len, out;

  len = str.length;

  i = 0;

  out = "";

  while(i < len) {

/* c1 */

do {

   c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];

} while(i < len && c1 == -1);

if(c1 == -1)

   break;

/* c2 */

do {

   c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];

} while(i < len && c2 == -1);

if(c2 == -1)

   break;

out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

/* c3 */

do {

   c3 = str.charCodeAt(i++) & 0xff;

   if(c3 == 61)

 return out;

   c3 = base64DecodeChars[c3];

} while(i < len && c3 == -1);

if(c3 == -1)

   break;

out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

/* c4 */

do {

   c4 = str.charCodeAt(i++) & 0xff;

   if(c4 == 61)

 return out;

   c4 = base64DecodeChars[c4];

} while(i < len && c4 == -1);

if(c4 == -1)

   break;

out += String.fromCharCode(((c3 & 0x03) << 6) | c4);

  }

  return out;

}

function utf16to8(str) {

  var out, i, len, c;

  out = "";

  len = str.length;

  for(i = 0; i < len; i++) {

c = str.charCodeAt(i);

if ((c >= 0x0001) && (c <= 0x007F)) {

   out += str.charAt(i);

} else if (c > 0x07FF) {

   out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));

   out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));

   out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));

} else {

   out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));

   out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));

}

  }

  return out;

}

function utf8to16(str) {

  var out, i, len, c;

  var char2, char3;

  out = "";

  len = str.length;

  i = 0;

  while(i < len) {

c = str.charCodeAt(i++);

switch(c >> 4)

{

  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:

   // 0xxxxxxx

   out += str.charAt(i-1);

   break;

  case 12: case 13:

   // 110x xxxx  10xx xxxx

   char2 = str.charCodeAt(i++);

   out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));

   break;

  case 14:

   // 1110 xxxx 10xx xxxx 10xx xxxx

   char2 = str.charCodeAt(i++);

   char3 = str.charCodeAt(i++);

   out += String.fromCharCode(((c & 0x0F) << 12) |

    ((char2 & 0x3F) << 6) |

    ((char3 & 0x3F) << 0));

   break;

}

  }

  return out;

}



function doit() {

  var f = document.f

  f.output.value = base64encode(utf16to8(f.source.value))

  f.decode.value = utf8to16(base64decode(f.output.value))

}
/script>

4.
.Net/C# 应用程序直接读取本地 Cookies 文件 (由于 WinXP SP2 调用 API: InternetGetCookie 无果)
From http://blog.csdn.net/playyuer/archive/2004/12/03/203431.aspx

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Win32;
public class Class1
{
static void Main(string[] args)
{
System.Console.WriteLine(GetCookiesFromFiles("et8")); //支持 WinXP SP2
System.Console.WriteLine(GetCookie("http://bbs.et8.net"));
System.Console.ReadLine();
}

[System.Runtime.InteropServices.DllImport("wininet.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
public static extern bool InternetGetCookie(string lpszUrlName, string lpszCookieName, StringBuilder lpszCookieData, ref int lpdwSize);

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
internal static extern Int32 GetLastError();

public static string GetCookie(string url) //Win32 API
{
int size = 1000;
StringBuilder sb = new StringBuilder(size);
if (!InternetGetCookie(url,"", sb,ref size))
{
Console.WriteLine("Error code:{0}", GetLastError());
}
return sb.ToString();
}

public static string GetCookiesFromFiles(string MasterDomain) //Cookies File
{
string S = null;
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", false);
if (key != null)
{
string val = null;
// foreach(string s in key.GetValueNames())
// {
// if (s.ToUpper() == "COOKIES")
// {
// val = (string) key.GetValue(s);
// break;
// }
// }
val = (string) key.GetValue("cooKies");
val = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Cookies);
// pay attention here

if (val!= null)
{
System.Console.WriteLine("用户 Cookies 文件目录: " + val);
string[] F = Directory.GetFiles(val);
string s = null;
int i;
Regex r = new Regex(@".*@" + MasterDomain + @"(\[\d+\])?\.txt");

for (i = 0; i < F.Length; i++)
{
if (r.IsMatch(F[i]))
{
s = F[i];
System.Console.WriteLine("用户 Cookies 文件: " + s);
}
}
if (s != null) //s 就是最新文件
{
StreamReader sr = new StreamReader(s);
s = null;
i = 1;
while ((s = sr.ReadLine())!= null)
{
if (s == "*" || s == "\n")
{
i = 0;
}
//每节只读两行
if (i == 1)
{
S += s;
}
else if (i == 2)
{
S += "=" + s + "; ";
}
i++;
}
}
}
}
return S;
}
}



<< Home

This page is powered by Blogger. Isn't yours?