Javascript 简单加密防止公布在网页上的邮箱被收集
需求描述:由于业务需求,很多企业网站都需要在自己网站上公布邮箱, 但是,却经常被一些自动的邮箱收集工具收集之后,受到垃圾邮件的困扰。
一般邮箱收集工具主要就是通过易做图的方式,扫描网页,然后通过正则表达式获取邮箱地址,比如匹配:mailto, 或者@ 符号,这样在网页中出现的<a href='mailto:xxxx@sss.com'>xxxx</a> 这样的邮箱都难逃脱被收集的厄运。有网站不得不将@符号替换为#号,然后再提醒用户自行替换。
技术方案:
首先考虑可以使用脚本来创建这样的链接:
<script>document.write('<a href="mailto:xxx@sss.com"></a>')</script>
然后只要对write中的内容稍作改动,即可轻松避免收集工具。
于是,改进如下:
<script>document.write('<a href="mailto:xxx"+"@"+"sss.com"></a>')</script>
这样,是不是就可以避免一部分工具呢?
然后再考虑复杂一些,这里加入一个简单的加密处理:
<script>
var s='amlioti:fn@osaaiansblotu.eocu.k';
var r='';
for(var i=0;i<s.length;i++,i++)
{
r=r+s.substring(i+1,i+2)+s.substring(i,i+1);
}
document.write('<a href="'+r+'"</a>');
</script>
仔细看一下很简单,无非就是把邮箱的字母位置进行颠倒,0和1颠倒,2和3颠倒……
然后为了让肉眼再无法辨识,使用script 的eval 方法,并且将这段脚本htmlEncoding
即变成:
<script>eval(unescape('%76%61%72%20%73%3d%27%61%6d%6c%69%6f%74%69%3a%66%6e%40%6f%73%61%61%69%61%6e%73%62%6c%6f%74%75%2e%65%6f%63%75%2e%6b%27%3b%76%61%72%20%72%3d%27%27%3b%66%6f%72%28%76%61%72%20%69%3d%30%3b%69%3c%73%2e%6c%65%6e%67%74%68%3b%69%2b%2b%2c%69%2b%2b%29%7b%72%3d%72%2b%73%2e%73%75%62%73%74%72%69%6e%67%28%69%2b%31%2c%69%2b%32%29%2b%73%2e%73%75%62%73%74%72%69%6e%67%28%69%2c%69%2b%31%29%7d%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%27%2b%72%2b%27%22%3e%69%6e%66%6f%40%61%73%69%61%6e%61%62%73%6f%6c%75%74%65%2e%63%6f%2e%75%6b%3c%2f%61%3e%27%29%3b'))</script>
如此一来,抓取工具就傻眼了。
附上生成处理脚本的C#代码:通过这个代码,就可以直接创建类似的脚本了:
string s = "mailto:info@asianabsolute.co.uk";
string r = "";
string lastchar = s.Length % 2 == 1 ? s[s.Length - 1].ToString() : "";
for (int i = 0; i < s.Length; i=i+2)
{
if(i<s.Length-1)
r = r + s.Substring(i+1 , 1) + s.Substring(i, 1);
}
r = r + lastchar;
string js = "var s='" + r + "';var r='';for(var i=0;i<s.length;i++,i++){r=r+s.substring(i+1,i+2)+s.substring(i,i+1)}document.write('<a href=\"'+r+'\">info@asianabsolute.co.uk</a>');";
Console.WriteLine(js);
Console.WriteLine(UrlEncode(js));
另外,将字符串保存为16进制显示的编码方法:
static string UrlEncode(string str)
{
StringBuilder sb = new StringBuilder();
byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str);
for (int i = 0; i < byStr.Length; i++)
{
sb.Append(@"%" + Convert.ToString(byStr[i], 16));
}
return (sb.ToString());
}
遗留问题:
这个方案是建立在收集工具未进行DOM检查的基础上的。如果收集工具在获取HTML 后又进行了页面脚本调用显示后,还是会在DOM中创建连接,这种情况下,就还是能够捕获了。
不过只要是破解的收益高于成本,应该是没有不能破解的加密的吧,所以,在做网站时,适当的使用这样的方式加密敏感信息,还是能够起一定作用的。
作者 chris-shao
补充:综合编程 , 安全编程 ,