作者:朱学武
在我的编程实践中,需要从 .NET 的 Web Form 页面传递加密的字符串信息 ( 如用户名和密码等 ) 到 ASP 页面,然后在该页面对该加密字符串进行解密。如果传递的不是加密串,通过 GET 或 POST 的方式就可以直接传递并在 ASP 页面中接收,但问题是在 .NET 的 Web Form 页面中加了密的字符串如何才能在 ASP 中进行解密呢?这主要由于 ASP 并不能直接访问由 .NET 提供的托管类和组件。这时我们就只能借助于 COM 组件来实现了,通过 COM 的互操作我们可通过 .NET 生成 COM 组件,然后在 ASP 页面中访问该 COM 组件就可以了。
本文实现的是将加密的用户名与密码从 .aspx 页面传递到 .asp 页面,下面就来介绍这些操作的具体步骤:
一、 制作具有加密、解密字符串的 .NET 程序集 (VS.NET 类库工程 )
这个程序集将会变成 COM 组件, 使用 DES 对称加密代码,可以加密码,可以加密解密,支持中文 !
// 文件名: StringCrypt.cs
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace jonson
{
// 首先建立接口,这个是 Com 必须使用的
[Guid("BF6F9C17-37FA-4ad9-9601-C11AD5316F2C")]
public interface IEncrypt
{
string Encrypt(string pToEncrypt,string sKey);
string Decrypt(string pToDecrypt,string sKey);
}
// 接口的实现
[Guid("3FBDBB63-3C36-4602-89E1-73EDB0F167D0")]
public class StringCrypt : IEncrypt
{
// 加密的方法
public string Encrypt(string pToEncrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
// 把字符串放到 byte 数组中
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
//byte[] inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);
// 建立加密对象的密钥和偏移量
// 原文使用 ASCIIEncoding.ASCII 方法的 GetBytes 方法
// 使得输入密码必须输入英文文本
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(),CryptoStreamMode.Write);
//Write the byte array into the crypto stream
//(It will end up in the memory stream)
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//Get the data back from the memory stream, and into a string
StringBuilder ret = new StringBuilder();
foreach(byte b in ms.ToArray())
{
//Format as hex
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
// 解密的方法
public string Decrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//Put the input string into the byte array
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for(int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
// 建立加密对象的密钥和偏移量,此值重要,不能修改
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
//Flush the data through the crypto stream into the memory stream
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//Get the decrypted data back from the memory stream
// 建立 StringBuilder 对象, CreateDecrypt 使用的是流对象,必须把解密后的文本变成流对象
StringBuilder ret = new StringBuilder();
return System.Text.Encoding.Default.GetString(ms.ToArray());
}
}
}
说明:注意上面的 Guid 是使用 vs.net 工具菜单里面的创建 guid 工具生成的,这个每个 Com 组件所必须的。输入密匙的时候,必须使用英文字符,区分大小写,且字符数量是 8 个,不能多也不能少,否则出错。
然后使用 vs.net 的“ Vsitual Studio .Net 工具” -->Vistual Studio .Net 命令提示符。在命令行内打下 cd c:\ < 回车 >
sn -k myKey.snk< 回车 >
这样就在 C 盘根目录下生成一个名叫 myKey.snk 的强名称文件,然后将其拷贝到上述工程目录中(与 StringCrypt.cs 文件同目录)后关闭提示符窗口。
在 vs.net 的那个类库工程自动生成的 AssemblyInfo.cs 文件内
把 [assembly: AssemblyKeyFile("")] 改成 [assembly: AssemblyKeyFile("../../myKey.snk ")]
把 [assembly: AssemblyVersion("1.0.*")] 改成 [assembly: AssemblyVersion("1.0.0.0")] // 注意:这时你的 Com 组件版本为 1.0.0.0 版
然后按 Shift + Ctrl + B 键生成 dll 库(使用 Release 模式), StringCrypt.dll 。这时候,程序集就建立成功了。
二、 注册该程序集并创建一个类型库
仍然使用开始菜单中的 Visual Studio .Net 命令提示符
进入你的项目目录,假设为 D:\project\bin\Release
在对话框中输入
d:< 回车 >
cd project\bin\release< 回车 >
然后输入 dir 命令可以看见 StringCrypt.dll 文件
然后输入: regasm StringCrypt.dll< 回车 >
然后就在这个目录下生成了 StringCrypt.tlb 类型库文件。不要关闭此提示符窗口。
这时候,这个 .dll 的 .net 程序集就变成一个标准的 Com 组件了,但是还不能用,必须让它变成全局 Com 组件。
这个 regasm 实用程序将创建一个类型库并在 Windows 注册表中对其进行注册,以便 COM Services 可以访问 .NET 组件。在使用 regasm 对 .NET 进行注册之后,标准的 Windows 客户就可以后期绑定组件中的类。注册组件的过程必须一次完成。在 .NET 组件被注册之后,所有的 COM 客户都可以访问它。
三、 将程序集添加到全局程序集缓存中
在使用 .NET 程序集之前,我们必须把程序集安装到全局的高速缓存中。为此进入 Visual Studio .Net 提示符窗口,输入
gacutil /I StringCrypt.dll< 回车 >
这时,你的这个 dll 就被复制到全局程序集缓存中了。也就是说无论在这个电脑的哪个硬盘上都可以使用此 dll 组件了。
四、 使用方法
1. 在 source.aspx 中生成加密串
using jonson;
…
jonson.StringCrypt crypt = new jonson.StringCrypt();
String tmpstr = username+"^"+password;
… …
strinfo = crypt.Encrypt(tmpstr,"fk58Fgju"); // fk58Fgju 为密匙
Response.Redirect("target.asp?info="+strinfo);
2. 在 target.asp 页面中接收并解密字符串
info = Request.QueryString(“info”)
set obj = Server.CreateObject("jonson.StringCrypt")
str1 = obj.Encrypt(info,"fk58Fgju") // 解密
本文的顺利实现,得到了网友 ** TomMax( ** ** 笑望人生 ** ** ) ** 等人的大力帮助,在此表示衷心的感谢。