1
yhj
2024-07-24 5e5d945e91568b973faa27d8ab0bcef99fc4a6c5
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#region
 
using System;
using System.Text;
using CSFrameworkV5.Common;
using CSFrameworkV5.Core;
 
#endregion
 
namespace CSFrameworkV5.WCFContract
{
    /// <summary>
    ///     WebService接口安全管理核心类
    /// </summary>
    public class WebServiceSecurity
    {
        private const int WCF_PREFIX_LEN = 16; /*预设伪造16位的数据(校验码)*/
        private const int WCF_SUFFIX_LEN = 8; /*预设伪造8位的数据(校验码)*/
 
        /// <summary>
        ///     加密用户登录凭证
        /// </summary>
        /// <param name="user">当前用户登录信息</param>
        /// <returns></returns>
        public static byte[] EncryptLoginer(Loginer user)
        {
            var user_byte = ZipTools.CompressionObject(user);
            var result =
                new byte[user_byte.Length + WCF_PREFIX_LEN + WCF_SUFFIX_LEN];
 
            var prefix = GetByteData(WCF_PREFIX_LEN);
            var suffix = GetByteData(WCF_SUFFIX_LEN);
 
            Array.Copy(user_byte, 0, result, WCF_PREFIX_LEN,
                user_byte.Length); //复制用户数据
            Array.Copy(prefix, 0, result, 0, prefix.Length); //复制头部伪码
            Array.Copy(suffix, 0, result, result.Length - WCF_SUFFIX_LEN,
                suffix.Length); //复制尾部伪码
 
            return result;
        }
 
        /// <summary>
        ///     用户登录信息加密后伪造指定位数的数据.
        /// </summary>
        private static byte[] GetByteData(int bit)
        {
            //128位伪造数据
            var chars = "ZA1D30A4B5C006S3LDFGHKD72C8E920D" +
                        "FJKQ30F506E7EQWERUIYUI02F1A0D0IO" +
                        "WEURTK236890L23B3B40C5E180D6F4D5" +
                        "EOPFDGHKW3IT6F4X90238503AS1094A2";
 
            if (bit < 2) bit = 2; //最少两位
 
            var n = GetRandomNum(chars.Length - bit - 2); //获取随机数
            var s = chars.Substring(n - 1, bit);
            var result = Encoding.ASCII.GetBytes(s);
            return result;
        }
 
        /// <summary>
        ///     自定义用户登录验证码
        /// </summary>
        /// <returns></returns>
        public static byte[] GetLoginTicket()
        {
            var result = Encoding.ASCII.GetBytes(Globals.WCF_LOGIN_TICKET);
            return result;
        }
 
        //获取随机数
        private static int GetRandomNum(int maxValue)
        {
            var seed = new Random();
            var randomNum = new Random();
            return randomNum.Next(1, maxValue);
        }
 
        /// <summary>
        ///     检查用户登录凭证,验证通过才允许访问后台数据.
        /// </summary>
        /// <param name="loginer">用户登录凭证</param>
        /// <returns></returns>
        public static Loginer ValidateLoginer(byte[] loginer)
        {
            //用户登录信息的长度小于伪码长度,数据包无效!
            if (loginer.Length < WCF_PREFIX_LEN + WCF_SUFFIX_LEN) //return null;
                throw new Exception("验证用户资料失败!");
 
            try
            {
                //用户登录信息的长度
                var objectArrar = new byte[loginer.Length -
                                           (WCF_PREFIX_LEN + WCF_SUFFIX_LEN)];
 
                //复制用户登录信息的数据包(去掉前后伪码)
                Array.Copy(loginer, WCF_PREFIX_LEN, objectArrar, 0,
                    objectArrar.Length);
 
                //转换为用户对象
                var user = (Loginer)ZipTools.DecompressionObject(objectArrar);
 
                if (user.Account.Length >= 1) //系统限制用户帐号的长度必须大于或等于1位
                    return user; //转换成功,返回用户对象.                
 
                throw new Exception("用户帐号不正确!");
            }
            catch
            {
                throw new Exception("验证用户资料失败!");
            }
        }
 
        /// <summary>
        ///     用户登录的验证码,防止用户恶意攻击Login接口.
        /// </summary>
        /// <param name="ticket">验证码</param>
        /// <returns></returns>
        public static bool ValidateLoginIdentity(byte[] validationTicket)
        {
            if (validationTicket == null ||
                validationTicket.Length < Encoding.ASCII
                    .GetBytes(Globals.WCF_LOGIN_TICKET).Length)
                throw new Exception("验证用户资料失败!");
 
            //取系统定义的验证码,你可以定义为128位.
            var TicketString =
                Encoding.ASCII.GetString(GetLoginTicket()).ToUpper();
 
            //客户端传来的验证码与系统定义的相比较
            var success =
                Encoding.ASCII.GetString(validationTicket).ToUpper() ==
                TicketString;
 
            if (success == false)
                throw new Exception("无效的验证码! 你还可以尝试X次,否则查你户口,封你IP!");
 
            return success;
 
            //
            //设计一个防止用户恶意攻击的管理器,记录每次调用的方法名及调用时间,
            //如果在指定的时间内调用超过最大限制数则视为恶意攻击,你可以暂时封杀
            //用户的IP.
            //
        }
    }
}