找回密码
 注册

QQ登录

只需一步,快速开始

查看: 5994|回复: 3

[原创]细节中的安全:基于表单防止密码星号查看器的脚本(IE、FF兼容)

[复制链接]
发表于 2007-9-10 02:05:57 | 显示全部楼层 |阅读模式
大家可能在填写完用户名或者密码时因为某种原因未登录而离开,这时大家可能因为密码框的星号而麻痹大意:以为密码不会被窥视,而放心离开。但是有一种软件可以直接查看星号隐藏下的密码原文,这就带来些安全隐患。不过本脚本可以让你的表单的密码区躲开密码星号查看软件的查看。

原理:生成一个ID为随机的隐藏Input,通过onkeyup事件实时捕获按键,并且复制到这个隐藏的Input里,同时将原密码区的值以“*”号替换掉。发送表单时,将隐藏Input的密码原文复制到原密码区并且销毁这个ID随机的隐藏Input。

下面注解如果在描述上有什么不妥欢迎提出

代码:

  1. /*
  2. 基于表单防止星号查看器的脚本
  3. 作者:oror@Blueidea
  4. 邮箱:pcn88#hotmail.com
  5. 网站:www.wyev.com
  6. */
  7. var aKey=new Array();
  8. //用于保存随机隐藏Input的ID值
  9. var aPrt=new Array();
  10. //用于保存所有受保护Input的name值
  11. var szFrm;
  12. //用于保存表单名
  13. frmProt={
  14.        
  15.         /*
  16.         获得ID对应对象
  17.         szID:[字符串]对象ID属性
  18.         */
  19.         $:function (szID){
  20.                
  21.                 return document.getElementById(szID);               
  22.                
  23.         },
  24.         /*
  25.         获得表单域对象
  26.         szFrmName:[字符串]表单的name值
  27.         */
  28.         $v:function (szFrmName){
  29.                
  30.                 return document.forms[szFrmName];               
  31.                
  32.         },
  33.         /*
  34.         获得表单域的Input标签对象
  35.         szName:[字符串]标签的name值
  36.         szFrmName:[字符串]表单的name值
  37.         */
  38.         $f:function (szName,szFrmName){
  39.                
  40.                 return frmProt.$v(szFrmName).elements[szName];               
  41.                
  42.         },
  43.         /*
  44.         绑定事件
  45.         obj:[OBJECT]对象
  46.         evn:[字符串]事件名称
  47.         f:函数
  48.         */
  49.         fAttach:function (obj,evn,f){
  50.                
  51.                 if(!obj)return ;               
  52.                 if(obj.attachEvent){
  53.                        
  54.                         obj.attachEvent("on"+evn,f);                       
  55.                        
  56.                 }
  57.                 if(obj.addEventListener){
  58.                        
  59.                         obj.addEventListener(evn,f,false);                       
  60.                        
  61.                 }
  62.                
  63.         },
  64.         /*
  65.         获得随机数字
  66.         dwIn:[数字]随机范围
  67.         */
  68.         fRand:function (dwIn){
  69.                
  70.                 return Math.floor(Math.random()*dwIn);               
  71.                
  72.         },
  73.         /*
  74.         获得随机字母与数字组合
  75.         dwLen:[数字]返回值长度
  76.         */
  77.         fRandom:function (dwLen){
  78.                
  79.                 var dwDx,szResult="",szTmp;               
  80.                 var aMySd=new Array();
  81.                 //建立数组用于保存随机字符,这里分成3组
  82.                 aMySd[0]="abcdefghijklmnopqrstuvwxyz";
  83.                 //第一组[0]:小写字母
  84.                 aMySd[1]="0987654321";
  85.                 //第二组[1]:数字
  86.                 aMySd[2]=aMySd[0].toUpperCase();
  87.                 //第三组[2]:大写字母
  88.                 for(var i=0;i<dwLen;i++){
  89.                         //依长度循环
  90.                         dwDx=frmProt.fRand(3);
  91.                         //获得一个随机数,范围0~2
  92.                         szTmp=aMySd[dwDx];
  93.                         //取出一组
  94.                         szResult+=szTmp.substr(frmProt.fRand(szTmp.length),1);
  95.                         //随机取出这一组中某个字符
  96.                        
  97.                 }
  98.                 return szResult;               
  99.                
  100.         },
  101.         /*
  102.         建立标签函数
  103.         szTarget:[字符串]父标签。生成的新标签将置于其中
  104.         szType:[字符串]要生成的标签类型
  105.         aProp:[数组]属性设置,如 Array("type=text","size=20")
  106.         */
  107.         fCreateTarget:function (szTarget,szType,aProp){
  108.                
  109.                 var aTmp;               
  110.                 var objLocation=frmProt.$v(szTarget);
  111.                 //获得父标签对象
  112.                 var objPreCreate=document.createElement(szType);
  113.                 //初始标签
  114.                 for(var i=0;i<aProp.length;i++){
  115.                         //设置属性循环开始
  116.                         aTmp=aProp[i].split("=");
  117.                         //按=号分开
  118.                         if(aTmp.length<2){
  119.                                 //注意为避免设置错误,这里做个判断
  120.                                 alert("错误的属性值设定");                               
  121.                                 return ;                               
  122.                                
  123.                         }
  124.                         objPreCreate.setAttribute(aTmp[0],aTmp[1]);
  125.                         //设置属性
  126.                        
  127.                 }
  128.                 objLocation.appendChild(objPreCreate);
  129.                 //建立这个标签
  130.                
  131.         },
  132.         /*
  133.         销毁标签
  134.         szTarget:[字符串]要销毁标签的父标签
  135.         szID:[字符串]要销毁标签ID
  136.         */
  137.         fRemoveTarget:function (szTarget,szID){
  138.                
  139.                 var objLocation=frmProt.$v(szTarget);
  140.                 //获得父标签对象
  141.                 objLocation.removeChild(frmProt.$(szID));               
  142.                
  143.         },
  144.         /*
  145.         创建隐藏Input标签
  146.         szBase:[字符串]父标签。生成的Input标签将置于其中
  147.         szName:[字符串]Input标签的name属性
  148.         */
  149.         fCreateHidden:function (szBase,szName){
  150.                
  151.                 var aHide=new Array("type=hidden","id="+szName,"value=");
  152.                 //设置属性
  153.                 frmProt.fCreateTarget(szBase,"input",aHide);
  154.                 //调用fCreateTarget创建
  155.                
  156.         },
  157.         /*获得event事件,主要为了兼容FireFox浏览器*/
  158.         fGetEvent:function (){
  159.                
  160.                 var objCaller=frmProt.fGetEvent.caller;               
  161.                 var objEvent,objResult=null;               
  162.                 while(objCaller!=null)
  163.                 {
  164.                        
  165.                         objEvent=objCaller.arguments[0];                       
  166.                         if(objEvent)objResult=objEvent;                       
  167.                         objCaller=objCaller.caller;                       
  168.                        
  169.                 }
  170.                 return objResult;               
  171.                
  172.         },
  173.         /*
  174.         获得按键
  175.         */
  176.         fGetKey:function (){
  177.                
  178.                 var e=frmProt.fGetEvent();
  179.                
  180.                 var dwKey=window.event?e.keyCode:e.which;               
  181.                 return dwKey;               
  182.                
  183.         },
  184.         /*
  185.         入口函数
  186.         szFrmName:[字符串]表单名
  187.         szProtName:[字符串]要保护的Input名,格式 "password|password2" 多个请用"|"分开
  188.         */
  189.         Init:function (szFrmName,szProtName){
  190.                
  191.                 aPrt=szProtName.split("|");
  192.                 //将受保护Input名分组
  193.                 var dwGetLen=aPrt.length;
  194.                 //获得分组长度
  195.                 var objPas;               
  196.                 if(dwGetLen<1)return ;
  197.                 //如果长度为0则中止
  198.                 for(var i=0;i<dwGetLen;i++){
  199.                         //循环
  200.                         aKey[i]=frmProt.fRandom(frmProt.fRand(64)+1);
  201.                         //随机英文和数字,长度范围1~63
  202.                         frmProt.fCreateHidden(szFrmName,aKey[i]);
  203.                         //创建隐藏Input表单
  204.                         objPas=frmProt.$f(aPrt[i],szFrmName);
  205.                         //获得受保护Input对象
  206.                         if(objPas==null)return ;
  207.                         //获取失败,则中止
  208.                         objPas.value="";                       
  209.                         frmProt.fAttach(objPas,"keyup",frmProt.fTask);
  210.                         //绑定onkeyup事件到受保护Input
  211.                        
  212.                 }
  213.                 frmProt.fAttach(frmProt.$v(szFrmName),"submit",frmProt.fSub);
  214.                 //绑定onsubmit到form表单
  215.                 szFrm=szFrmName;
  216.                 //将传入的表单名赋给全局变量
  217.                
  218.         },
  219.         //提交表单触发函数:将隐藏Input的内容复制到受保护Input里,销毁隐藏Input
  220.         fSub:function (){
  221.                
  222.                 for(var i=0;i<aPrt.length;i++){
  223.                        
  224.                         frmProt.$f(aPrt[i],szFrm).value=frmProt.$(aKey[i]).value;
  225.                         //将隐藏Input的内容复制到受保护Input里
  226.                         frmProt.fRemoveTarget(szFrm,aKey[i]);
  227.                         //销毁隐藏Input
  228.                        
  229.                 }
  230.                 return true;               
  231.                
  232.         },
  233.         //Input实时保护函数
  234.         fTask:function (){
  235.                
  236.                 var dwKeyCode,szPrt,szOrg,szTemp,dwSta,szA,szB,objMouse;               
  237.                 dwKeyCode=frmProt.fGetKey();               
  238.                 if(dwKeyCode!=37&&dwKeyCode!=39){
  239.                         //判断并且过滤掉光标左右移动按键,否则光标会受selection.createRange影响
  240.                         for(var i=0;i<aPrt.length;i++){
  241.                                
  242.                                 if(!frmProt.$(aKey[i])){
  243.                                         //判断一下隐藏Input是否存在。
  244.                                         alert("隐藏域已经销毁,请重新加载本页!");                                       
  245.                                         return ;                                       
  246.                                        
  247.                                 }
  248.                                 szPrt=frmProt.$f(aPrt[i],szFrm).value;
  249.                                 //得到受保护Input的Value值
  250.                                 szOrg=frmProt.$(aKey[i]).value;
  251.                                 //得到隐藏Input的Value值
  252.                                 if(szPrt!=""){
  253.                                         //如果不为空
  254.                                         dwSta=szOrg.length-szPrt.length;                                       
  255.                                         if(dwSta==1){
  256.                                                 //这里主要判断删除字符
  257.                                                 if(document.all){
  258.                                                         //IE
  259.                                                         objMouse=document.selection.createRange();
  260.                                                         //作用:定位光标
  261.                                                         objMouse.setEndPoint("StartToStart",frmProt.$f(aPrt[i],szFrm).createTextRange());                                                       
  262.                                                         dwSta=objMouse.text.length;
  263.                                                         //获得光标的位置
  264.                                                        
  265.                                                 }else {
  266.                                                         //FireFox
  267.                                                         objMouse=frmProt.$f(aPrt[i],szFrm).selectionStart;                                                       
  268.                                                         dwSta=objMouse;                                                       
  269.                                                        
  270.                                                 }
  271.                                                 szA=szOrg.substr(0,dwSta);
  272.                                                 //从第一个字符截取到光标位置长度的字符串。
  273.                                                 szB=szOrg.substr(dwSta+1,szOrg.length);
  274.                                                 //从光标位置并且跳掉一个字符截取到整个字符串长度的字符,这里实现删除字符。
  275.                                                 frmProt.$(aKey[i]).value=szA+szB;
  276.                                                 //组成新的字符串并拷贝到隐藏的Input
  277.                                                
  278.                                         }else if(dwSta>1){
  279.                                                 //这里由于无法对于连续删除按键进行判断,于是发现用户这样操作,则重置表单
  280.                                                 frmProt.$(aKey[i]).value="";                                               
  281.                                                 frmProt.$f(aPrt[i],szFrm).value="";                                               
  282.                                                
  283.                                         }else {
  284.                                                
  285.                                                 szTemp=szPrt.replace(/\*/g,"");
  286.                                                 //替换掉所有*获得插入字符
  287.                                                 dwSta=szPrt.indexOf(szTemp);
  288.                                                 //判断最新插入字符的位置
  289.                                                 szA=szOrg.substr(0,dwSta);
  290.                                                 //从第一个字符截取到这个插入字符的位置
  291.                                                 szB=szOrg.substr(dwSta,szPrt.length);
  292.                                                 //从这个插入字符位置截取到字符串最后
  293.                                                 frmProt.$(aKey[i]).value=szA+szTemp+szB;
  294.                                                 //组成新的字符串并拷贝到隐藏的Input
  295.                                                 frmProt.$f(aPrt[i],szFrm).value=szPrt.replace(/./ig,"*");
  296.                                                 //替换掉受保护Input的值为*
  297.                                                
  298.                                         }
  299.                                        
  300.                                 }else {
  301.                                        
  302.                                         frmProt.$(aKey[i]).value="";
  303.                                         //如果受保护Input值为空,清空隐藏Input的值
  304.                                        
  305.                                 }
  306.                                
  307.                         }
  308.                        
  309.                 }
  310.                
  311.         }
  312.        
  313. }
复制代码


调用方式

window.onload=function(){
frmProt.Init("表单名","要保护的密码区域,多个请用‘|’分隔");
}

演示HTML

 提示:您可以先修改部分代码再运行



测试接收的ASP


  1. <%
  2. Dim szFrm
  3. For Each szFrm In Request.Form
  4. Response.Write szFrm & "=" & Request.Form(szFrm) & "<br />"
  5. Next
  6. %>
复制代码


目前只支持单个表单域中的一个或者多个input标签。

这里还可以扩展一下,比如说随机生成一串字符作为密匙,用密匙实时加密密码原文。然后发送到服务器端,由服务器端根据密匙解密密码原文。

由于本人能力有限,如果上述代码有什么错误或者你有更好的实现代码欢迎交流!谢谢!!

[[i] 本帖最后由 oror 于 2007-9-11 21:20 编辑 ]

评分

参与人数 1威望 +2 收起 理由
mozart0 + 2 原创内容

查看全部评分

 楼主| 发表于 2007-9-11 20:47:35 | 显示全部楼层
自己顶一下
回复 支持 反对

使用道具 举报

发表于 2007-9-11 21:15:28 | 显示全部楼层
代码写出来专门给人看的却不缩进,细节啊,兄弟

[[i] 本帖最后由 mozart0 于 2007-9-11 21:17 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-11 21:20:40 | 显示全部楼层
已经缩进过了,谢谢提醒
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备19000417号-2 )

GMT+8, 2021-12-3 05:43 , Processed in 0.059960 second(s), 13 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表