最近项目中有个需求,大致说起来就是:公司上线了一个网站,但是需要对这个网站做使用时间限制,也就是常说的授权。
由于时间紧迫,我的实现思路如下:
1、编写注册机代码,用注册机形成授权文件,授权文件为一个xml字符串,包括开始时间与结束时间节点,然后用加密方法对形成的xml字符串加密
2、将授权文件放到网站发布目录下,修改原网站中的代码,解析授权文件中加密的字符串并进一步判断
实现代码如下:
注册机部分代码:
Base_64 bs = new Base_64(); DateTime dtkssj = dtpKssj.Value; string ksrq = dtkssj.ToString("yyyy-MM-dd"); DateTime dtjssj = dtpJssj.Value; string jsrq = dtjssj.ToString("yyyy-MM-dd"); string xmlString = ""; xmlString += "<KSRQ>" + ksrq + "</KSRQ>"; xmlString += "<JSRQ>" + jsrq + "</JSRQ>"; string jmzf = bs.encrypt(xmlString); string dirPath = Application.StartupPath; string filePath = dirPath + "\\" + "授权文件,.ini"; if (!File.Exists(filePath)) { File.Create(filePath); } FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); fs.SetLength(0); sw.Write(jmzf); sw.Close(); MessageBox.Show("注册成功");
注册机的主体实现思路如上文所说,用特定格式的xml字符串控制,然后用特定方式加密。
加密类的部分代码:
public string encrypt(string str) { int len = str.Length; if (str == null) return "";//throw new Exception("NULL pointer."); if (len == 0) return str; string pTmp = ""; pTmp = str; string dest = ""; for (int i = 0; i < len; i++) { char ch = pTmp[i]; int idx1 = ch >> 2 & 0x3f; int idx2 = ch << 4 & 0x30; dest += s_keys[idx1]; if (++i == len) { dest += s_keys[idx2]; break; } //ch = pTmp.charAt(i); ch = pTmp[i]; idx1 = idx2 | ch >> 4 & 0xf; idx2 = ch << 2 & 0x3f; dest += s_keys[idx1]; if (++i == len) { dest += s_keys[idx2]; break; } ch = pTmp[i]; idx1 = idx2 | ch >> 6 & 0x3; idx2 = ch & 0x3f; dest += s_keys[idx1]; dest += s_keys[idx2]; } return dest;//dest.toString(); }
解密类的部分代码:
public string decrypt(string str) { if (str == null) return "";//throw new Exception("NULL pointer."); int len = str.Length; if (len == 0) return str; string dest = ""; //StringBuffer dest = new StringBuffer(); for (int j = 0; j < len; j++) { char ch = str[j]; int i; for (i = 0; i < 64; i++) if (s_keys[i] == ch) break; char tempDest = (char)(i << 2); if (++j == len) { dest += tempDest; //dest.append(tempDest); break; } ch = str[j]; for (i = 0; i < 64; i++) if (s_keys[i] == ch) break; tempDest |= Convert.ToChar(i >> 4); dest += tempDest; //dest.append(tempDest |= i >> 4); int temp = (i & 0xf) << 4; if (++j == len) break; ch = str[j]; for (i = 0; i < 64; i++) if (s_keys[i] == ch) break; dest += (char)(temp | i >> 2); //dest.append((char)(temp | i >> 2)); temp = (i & 0x3) << 6; if (++j == len) break; ch = str[j]; for (i = 0; i < 64; i++) if (s_keys[i] == ch) break; dest += (char)(temp | i); //dest.append((char)(temp | i)); } return dest;//dest.toString(); }
网站部分解密授权文件部分代码:
string dirPath = Server.MapPath(""); string filePath = dirPath + "\\" + "授权文件.ini"; if (!System.IO.File.Exists(filePath)) { //没有授权文件 显示未授权 } else { System.IO.StreamReader sr = new System.IO.StreamReader(filePath, Encoding.UTF8); string content = sr.ReadToEnd().ToString(); sr.Close(); Base_64 bs1 = new Base_64(); string jmzf = bs1.decrypt(content); System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();//实例化一个XmlDocument对像 xmldoc.LoadXml(jmzf); System.Xml.XmlNode xnKsrq = xmldoc.SelectSingleNode("KSRQ"); string ksrq = xnKsrq.InnerText; System.Xml.XmlNode xnJsrq = xmldoc.SelectSingleNode("JSRQ"); string jsrq = xnJsrq.InnerText; DateTime dtKsrq = Convert.ToDateTime(ksrq); DateTime dtJsrq = Convert.ToDateTime(jsrq); DateTime dtNow = DateTime.Now.AddDays(1); int ks = DateTime.Compare(dtKsrq, dtNow); int js = DateTime.Compare(dtJsrq, dtNow); if (ks > 0 || js < 0) { //显示授权到期 } }
在网站代码中直接获取到这个授权文件,然后用对称的方式解密并判断授权的开始日期与结束日期与服务器日期做比对。
总结:代码很简单,甚至是有点简陋,这里希望抛砖引玉,有没有更好的实现思路?这种用文件授权的方式进行的加密是不是容易被破解?。。。
还望各位赐教.....