最近项目中有个需求,大致说起来就是:公司上线了一个网站,但是需要对这个网站做使用时间限制,也就是常说的授权。
由于时间紧迫,我的实现思路如下:
1、编写注册机代码,用注册机形成授权文件,授权文件为一个xml字符串,包括开始时间与结束时间节点,然后用加密方法对形成的xml字符串加密
2、将授权文件放到网站发布目录下,修改原网站中的代码,解析授权文件中加密的字符串并进一步判断
实现代码如下:
注册机部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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字符串控制,然后用特定方式加密。
加密类的部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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();
}
|
解密类的部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
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();
}
|
网站部分解密授权文件部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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)
{
//显示授权到期
}
}
|
在网站代码中直接获取到这个授权文件,然后用对称的方式解密并判断授权的开始日期与结束日期与服务器日期做比对。
总结:代码很简单,甚至是有点简陋,这里希望抛砖引玉,有没有更好的实现思路?这种用文件授权的方式进行的加密是不是容易被破解?。。。
还望各位赐教.....