asp加密

去年帮一个客户排查服务器入侵,翻日志时发现攻击者上传的 webshell 文件名全是 xx.asp;.jpg 这种格式。IIS 6.0 解析漏洞,老掉牙的手法,但依然有人中招。问题出在他们用的 ASP 加密组件上——版本太老,密钥硬编码在源码里,攻击者拿到源码后直接解密了数据库连接串。

ASP 加密这事,很多人第一反应是 MD5。MD5 不是加密,是哈希,而且早就被撞得千疮百孔。2004 年王小云团队就给出了碰撞算法,现在随便一台普通电脑几秒钟能造出两个 MD5 相同的不同文件。拿它存密码,等于把钥匙挂在门锁上。

真正在 ASP 里做加密,绕不开几个东西:Scripting.Encoder、CAPICOM、还有 Windows 自带的 CryptoAPI。Scripting.Encoder 只能做脚本混淆,防君子不防小人,用微软自己的解码工具就能还原。CAPICOM 倒是正经的加密组件,但微软 2009 年就停止支持了,现在还在用的项目,基本等于裸奔。

我见过最离谱的一个案例。某企业内网系统用 ASP 写登录模块,密码字段在数据库里存的是明文。问开发为什么,答曰“反正内网”。后来做等保测评,直接被判高危。整改方案是用 SHA256 加盐哈希,结果开发图省事,盐值写死成 "salt123"。这跟没加盐区别不大,彩虹表稍微定制一下就能破。

ASP 本身没有内置的现代加密库。要在经典 ASP 里用 AES,得靠 COM 组件或者 Server.CreateObject 调用 .NET 的 System.Security.Cryptography。具体做法是在 .NET 里写一个 COM 可见的类,编译成 DLL,注册到服务器上,然后 ASP 通过 Server.CreateObject("YourNamespace.CryptoClass") 调用。听起来麻烦,但这是目前最稳妥的路子。

密钥管理是另一个坑。很多教程直接把密钥写在 ASP 文件里,比如 Const SECRET_KEY = "mysecretkey123"。服务器一旦被上传 webshell,攻击者第一件事就是翻 global.asa 和 conn.asp。密钥得放在注册表或者环境变量里,通过 WScript.Shell 读取,至少增加一层门槛。

还有一个容易被忽略的点:ASP 的 SessionID 默认是明文传输的。如果站点没有强制 HTTPS,会话劫持比破解加密数据容易得多。加密做得再好,传输层裸奔,等于白干。

说个实际能用的方案。用 .NET 写一个 AES-256-CBC 的 COM 组件,密钥从注册表读,IV 每次随机生成并附在密文前面。ASP 端调用加密函数,把结果 Base64 编码后存库。解密时先 Base64 解码,取前 16 字节做 IV,剩下的做密文。这套流程在经典 ASP 环境里跑了好几年,没出过问题。

最后提一句,别用 Microsoft.XMLHTTP 去调外部加密 API。延迟高,而且一旦网络抖动,登录直接失败。加密这事,能本地做就本地做。