要说SQL注入还是要感谢我师傅的,听他说在程序开发过程中,我们经常会遇到SQL注入问题,也就是指令隐码攻击。
再说通俗点就是利用程序员对用户输入数据的合法性检测不严或不检测的特点,故意从客户端提交特殊的代码,从而收集程序及服务器的信息,从而获取想得到的资料。
想要避免SQL注入,在网上的答案也是五花八门,毕竟要站在巨人肩膀上学习,也要注重总结,下面就是我对避免SQL注入的理解加总结~~
从个人问题上来说:
对与高级密码来说避免SQL注入真的还是有很大的帮助的,传统的加解密大致可以分为三种:
1、对称加密:
即加密方和解密方都使用相同的加密算法和密钥,这种方案的密钥的保存非常关键,因为算法是公开的,而密钥是保密的,一旦密匙泄露,黑客仍然可以轻易解密。常见的对称加密算法有:AES、DES等。
EG:
AES加密算法基于排列和置换运算。排列是对数据重新进行安排,置换是将一个数据单元替换为另一个,下面是窗体设计及源码(能力有限,用vb6.0实现的):


2、非对称加密:
即使用不同的密钥来进行加解密,密钥被分为公钥和私钥,用私钥加密的数据必须使用公钥来解密,同样用公钥加密的数据必须用对应的私钥来解密,常见的非对称加密算法有:RSA等。
EG:
RSA分享一个连接,分别是窗口设计和模块集中代码~
http://read.pudn.com/downloads199/sourcecode/crypt/936560/RSA(VB)/RSACal.cls__.htm
3、不可逆加密:
利用哈希算法使数据加密之后无法解密回原数据,这样的哈希算法常用的有:md5、SHA-1等。
EG:
md5简介~~http://baike.baidu.com/link?url=_I1k8M8CkdA0VjXLK4Od-EGQuxdpx3yZkyJ6GDv37sTMno-ZjHymOCkYDyQH25KSasvK-bHiu9s_8KMVur_dAa
下面是代码~~
005 | DataBindingBehavior = 0 |
006 | DataSourceBehavior = 0 |
007 | MTSTransactionMode = 0 |
009 | Attribute VB_Name = "Cls_MD5" |
010 | Attribute VB_GlobalNameSpace = False |
011 | Attribute VB_Creatable = True |
012 | Attribute VB_PredeclaredId = False |
013 | Attribute VB_Exposed = True |
014 | Private Const OFFSET_4 = 4294967296# |
015 | Private Const MAXINT_4 = 2147483647 |
016 | Private Const S11 = 7 |
017 | Private Const S12 = 12 |
018 | Private Const S13 = 17 |
019 | Private Const S14 = 22 |
020 | Private Const S21 = 5 |
021 | Private Const S22 = 9 |
022 | Private Const S23 = 14 |
023 | Private Const S24 = 20 |
024 | Private Const S31 = 4 |
025 | Private Const S32 = 11 |
026 | Private Const S33 = 16 |
027 | Private Const S34 = 23 |
028 | Private Const S41 = 6 |
029 | Private Const S42 = 10 |
030 | Private Const S43 = 15 |
031 | Private Const S44 = 21 |
032 | Private State(4) As Long |
033 | Private ByteCounter As Long |
034 | Private ByteBuffer(63) As Byte |
035 | Property Get RegisterA() As String |
038 | Property Get RegisterB() As String |
041 | Property Get RegisterC() As String |
044 | Property Get RegisterD() As String |
047 | Public Function DigestFileToHexStr(FileName As String ) As String |
048 | Open FileName For Binary Access Read As #1 |
052 | If Loc(1) < LOF(1) Then |
053 | ByteCounter = ByteCounter + 64 |
054 | MD5Transform ByteBuffer |
057 | ByteCounter = ByteCounter + (LOF(1) Mod 64) |
060 | DigestFileToHexStr = GetValues |
062 | Public Function DigestStrToHexStr(SourceString As String ) As String |
064 | MD5Update LenB(SourceString), StringToArray(SourceString) |
066 | DigestStrToHexStr = GetValues |
068 | Private Function StringToArray(InString As String ) As Byte () |
070 | Dim bytBuffer() As Byte |
071 | ReDim bytBuffer(LenB(InString)) |
072 | For i = 0 To LenB(InString) - 1 |
073 | bytBuffer(i) = AscB(MidB(InString, i + 1, 1)) |
075 | StringToArray = bytBuffer |
077 | Private Function GetValues() As String |
078 | GetValues = LongToString(State(1)) & LongToString(State(2)) & LongToString(State(3)) & LongToString(State(4)) |
080 | Private Function LongToString(Num As Long ) As String |
087 | LongToString = "0" & Hex(a) |
089 | LongToString = Hex(a) |
091 | b = (Num And &HFF00&) \ 256 |
093 | LongToString = LongToString & "0" & Hex(b) |
095 | LongToString = LongToString & Hex(b) |
097 | c = (Num And &HFF0000) \ 65536 |
099 | LongToString = LongToString & "0" & Hex(c) |
101 | LongToString = LongToString & Hex(c) |
104 | d = ((Num And &H7F000000) \ 16777216) Or &H80& |
106 | d = (Num And &HFF000000) \ 16777216 |
109 | LongToString = LongToString & "0" & Hex(d) |
111 | LongToString = LongToString & Hex(d) |
115 | Private Sub MD5Init() |
117 | State(1) = UnsignedToLong(1732584193#) |
118 | State(2) = UnsignedToLong(4023233417#) |
119 | State(3) = UnsignedToLong(2562383102#) |
120 | State(4) = UnsignedToLong(271733878#) |
125 | Public Sub MD5Final() |
126 | Dim dblBits As Double |
127 | Dim padding(72) As Byte |
128 | Dim lngBytesBuffered As Long |
130 | dblBits = ByteCounter * 8 |
132 | lngBytesBuffered = ByteCounter Mod 64 |
133 | If lngBytesBuffered <= 56 Then |
134 | MD5Update 56 - lngBytesBuffered, padding |
136 | MD5Update 120 - ByteCounter, padding |
138 | padding(0) = UnsignedToLong(dblBits) And &HFF& |
139 | padding(1) = UnsignedToLong(dblBits) \ 256 And &HFF& |
140 | padding(2) = UnsignedToLong(dblBits) \ 65536 And &HFF& |
141 | padding(3) = UnsignedToLong(dblBits) \ 16777216 And &HFF& |
151 | Public Sub MD5Update(InputLen As Long , InputBuffer() As Byte ) |
156 | Dim lngBufferedBytes As Long |
157 | Dim lngBufferRemaining As Long |
159 | lngBufferedBytes = ByteCounter Mod 64 |
160 | lngBufferRemaining = 64 - lngBufferedBytes |
161 | ByteCounter = ByteCounter + InputLen |
163 | If InputLen >= lngBufferRemaining Then |
164 | For II = 0 To lngBufferRemaining - 1 |
165 | ByteBuffer(lngBufferedBytes + II) = InputBuffer(II) |
167 | MD5Transform ByteBuffer |
168 | lngRem = (InputLen) Mod 64 |
170 | For i = lngBufferRemaining To InputLen - II - lngRem Step 64 |
172 | ByteBuffer(j) = InputBuffer(i + j) |
174 | MD5Transform ByteBuffer |
181 | For K = 0 To InputLen - i - 1 |
182 | ByteBuffer(lngBufferedBytes + K) = InputBuffer(i + K) |
188 | Private Sub MD5Transform(Buffer() As Byte ) |
200 | FF a, b, c, d, x(0), S11, -680876936 |
201 | FF d, a, b, c, x(1), S12, -389564586 |
202 | FF c, d, a, b, x(2), S13, 606105819 |
203 | FF b, c, d, a, x(3), S14, -1044525330 |
204 | FF a, b, c, d, x(4), S11, -176418897 |
205 | FF d, a, b, c, x(5), S12, 1200080426 |
206 | FF c, d, a, b, x(6), S13, -1473231341 |
207 | FF b, c, d, a, x(7), S14, -45705983 |
208 | FF a, b, c, d, x(8), S11, 1770035416 |
209 | FF d, a, b, c, x(9), S12, -1958414417 |
210 | FF c, d, a, b, x(10), S13, -42063 |
211 | FF b, c, d, a, x(11), S14, -1990404162 |
212 | FF a, b, c, d, x(12), S11, 1804603682 |
213 | FF d, a, b, c, x(13), S12, -40341101 |
214 | FF c, d, a, b, x(14), S13, -1502002290 |
215 | FF b, c, d, a, x(15), S14, 1236535329 |
217 | GG a, b, c, d, x(1), S21, -165796510 |
218 | GG d, a, b, c, x(6), S22, -1069501632 |
219 | GG c, d, a, b, x(11), S23, 643717713 |
220 | GG b, c, d, a, x(0), S24, -373897302 |
221 | GG a, b, c, d, x(5), S21, -701558691 |
222 | GG d, a, b, c, x(10), S22, 38016083 |
223 | GG c, d, a, b, x(15), S23, -660478335 |
224 | GG b, c, d, a, x(4), S24, -405537848 |
225 | GG a, b, c, d, x(9), S21, 568446438 |
226 | GG d, a, b, c, x(14), S22, -1019803690 |
227 | GG c, d, a, b, x(3), S23, -187363961 |
228 | GG b, c, d, a, x(8), S24, 1163531501 |
229 | GG a, b, c, d, x(13), S21, -1444681467 |
230 | GG d, a, b, c, x(2), S22, -51403784 |
231 | GG c, d, a, b, x(7), S23, 1735328473 |
232 | GG b, c, d, a, x(12), S24, -1926607734 |
234 | HH a, b, c, d, x(5), S31, -378558 |
235 | HH d, a, b, c, x(8), S32, -2022574463 |
236 | HH c, d, a, b, x(11), S33, 1839030562 |
237 | HH b, c, d, a, x(14), S34, -35309556 |
238 | HH a, b, c, d, x(1), S31, -1530992060 |
239 | HH d, a, b, c, x(4), S32, 1272893353 |
240 | HH c, d, a, b, x(7), S33, -155497632 |
241 | HH b, c, d, a, x(10), S34, -1094730640 |
242 | HH a, b, c, d, x(13), S31, 681279174 |
243 | HH d, a, b, c, x(0), S32, -358537222 |
244 | HH c, d, a, b, x(3), S33, -722521979 |
245 | HH b, c, d, a, x(6), S34, 76029189 |
246 | HH a, b, c, d, x(9), S31, -640364487 |
247 | HH d, a, b, c, x(12), S32, -421815835 |
248 | HH c, d, a, b, x(15), S33, 530742520 |
249 | HH b, c, d, a, x(2), S34, -995338651 |
251 | II a, b, c, d, x(0), S41, -198630844 |
252 | II d, a, b, c, x(7), S42, 1126891415 |
253 | II c, d, a, b, x(14), S43, -1416354905 |
254 | II b, c, d, a, x(5), S44, -57434055 |
255 | II a, b, c, d, x(12), S41, 1700485571 |
256 | II d, a, b, c, x(3), S42, -1894986606 |
257 | II c, d, a, b, x(10), S43, -1051523 |
258 | II b, c, d, a, x(1), S44, -2054922799 |
259 | II a, b, c, d, x(8), S41, 1873313359 |
260 | II d, a, b, c, x(15), S42, -30611744 |
261 | II c, d, a, b, x(6), S43, -1560198380 |
262 | II b, c, d, a, x(13), S44, 1309151649 |
263 | II a, b, c, d, x(4), S41, -145523070 |
264 | II d, a, b, c, x(11), S42, -1120210379 |
265 | II c, d, a, b, x(2), S43, 718787259 |
266 | II b, c, d, a, x(9), S44, -343485551 |
267 | State(1) = LongOverflowAdd(State(1), a) |
268 | State(2) = LongOverflowAdd(State(2), b) |
269 | State(3) = LongOverflowAdd(State(3), c) |
270 | State(4) = LongOverflowAdd(State(4), d) |
273 | Private Sub Decode(Length As Integer , OutputBuffer() As Long , InputBuffer() As Byte ) |
274 | Dim intDblIndex As Integer |
275 | Dim intByteIndex As Integer |
278 | For intByteIndex = 0 To Length - 1 Step 4 |
279 | dblSum = InputBuffer(intByteIndex) + _ |
280 | InputBuffer(intByteIndex + 1) * 256# + _ |
281 | InputBuffer(intByteIndex + 2) * 65536# + _ |
282 | InputBuffer(intByteIndex + 3) * 16777216# |
283 | OutputBuffer(intDblIndex) = UnsignedToLong(dblSum) |
284 | intDblIndex = intDblIndex + 1 |
287 | Private Function FF(a As Long , _ |
294 | a = LongOverflowAdd4(a, (b And c) Or ( Not (b) And d), x, ac) |
295 | a = LongLeftRotate(a, s) |
296 | a = LongOverflowAdd(a, b) |
298 | Private Function GG(a As Long , _ |
305 | a = LongOverflowAdd4(a, (b And d) Or (c And Not (d)), x, ac) |
306 | a = LongLeftRotate(a, s) |
307 | a = LongOverflowAdd(a, b) |
309 | Private Function HH(a As Long , _ |
316 | a = LongOverflowAdd4(a, b Xor c Xor d, x, ac) |
317 | a = LongLeftRotate(a, s) |
318 | a = LongOverflowAdd(a, b) |
320 | Private Function II(a As Long , _ |
327 | a = LongOverflowAdd4(a, c Xor (b Or Not (d)), x, ac) |
328 | a = LongLeftRotate(a, s) |
329 | a = LongOverflowAdd(a, b) |
331 | Function LongLeftRotate(value As Long , bits As Long ) As Long |
335 | If bits = 0 Then LongLeftRotate = value: Exit Function |
337 | lngSign = value And &HC0000000 |
338 | value = (value And &H3FFFFFFF) * 2 |
339 | value = value Or ((lngSign < 0) And 1) Or ( CBool (lngSign And _ |
340 | &H40000000) And &H80000000) |
342 | LongLeftRotate = value |
344 | Private Function LongOverflowAdd(Val1 As Long , Val2 As Long ) As Long |
345 | Dim lngHighWord As Long |
346 | Dim lngLowWord As Long |
347 | Dim lngOverflow As Long |
348 | lngLowWord = (Val1 And &HFFFF&) + (Val2 And &HFFFF&) |
349 | lngOverflow = lngLowWord \ 65536 |
350 | lngHighWord = (((Val1 And &HFFFF0000) \ 65536) + ((Val2 And &HFFFF0000) \ 65536) + lngOverflow) And &HFFFF& |
351 | LongOverflowAdd = UnsignedToLong((lngHighWord * 65536#) + (lngLowWord And &HFFFF&)) |
353 | Private Function LongOverflowAdd4(Val1 As Long , Val2 As Long , val3 As Long , val4 As Long ) As Long |
354 | Dim lngHighWord As Long |
355 | Dim lngLowWord As Long |
356 | Dim lngOverflow As Long |
357 | lngLowWord = (Val1 And &HFFFF&) + (Val2 And &HFFFF&) + (val3 And &HFFFF&) + (val4 And &HFFFF&) |
358 | lngOverflow = lngLowWord \ 65536 |
359 | lngHighWord = (((Val1 And &HFFFF0000) \ 65536) + _ |
360 | ((Val2 And &HFFFF0000) \ 65536) + _ |
361 | ((val3 And &HFFFF0000) \ 65536) + _ |
362 | ((val4 And &HFFFF0000) \ 65536) + _ |
363 | lngOverflow) And &HFFFF& |
364 | LongOverflowAdd4 = UnsignedToLong((lngHighWord * 65536#) + (lngLowWord And &HFFFF&)) |
366 | Private Function UnsignedToLong(value As Double ) As Long |
367 | If value < 0 Or value >= OFFSET_4 Then Error 6 |
368 | If value <= MAXINT_4 Then |
369 | UnsignedToLong = value |
371 | UnsignedToLong = value - OFFSET_4 |
374 | Private Function LongToUnsigned(value As Long ) As Double |
376 | LongToUnsigned = value + OFFSET_4 |
378 | LongToUnsigned = value |
从程序员问题来讲:
1.多多使用SQL Server数据库自带的安全参数
为了减少注入式攻击对于SQL Server数据库的不良影响,在SQLServer数据库专门设计了相对安全的SQL参数。在数据库设计过程中,工程师要尽量采用这些参数来杜绝恶意的SQL注入式攻击。
如在SQL Server数据库中提供了Parameters集合。这个集合提供了类型检查和长度验证的功能。如果管理员采用了Parameters这个集合的话,则用户输入的内容将被视为字符值而不是可执行代码。即使用户输入的内容中含有可执行代码,则数据库也会过滤掉。因为此时数据库只把它当作普通的字符来处理。
使用Parameters集合的另外一个优点是可以强制执行类型和长度检查,范围以外的值将触发异常。如果用户输入的值不符合指定的类型与长度约束,就会发生异常,并报告给管理员。如上面这个案例中,如果员工编号定义的数据类型为字符串型,长度为10个字符。而用户输入的内容虽然也是字符类型的数据,但是其长度达到了20个字符。则此时就会引发异常,因为用户输入的内容长度超过了数据库字段长度的限制。
2.加强对用户输入的验证
总体来说,防治SQL注入式攻击可以采用两种方法,一是加强对用户输入内容的检查与验证;
二是强迫使用参数化语句来传递用户输入的内容。在SQLServer数据库中,有比较多的用户输入内容验证工具,可以帮助管理员来对付SQL注入式攻击。测试字符串变量的内容,只接受所需的值。拒绝包含二进制数据、转义序列和注释字符的输入内容。这有助于防止脚本注入,防止某些缓冲区溢出攻击。测试用户输入内容的大小和数据类型,强制执行适当的限制与转换。这即有助于防止有意造成的缓冲区溢出,对于防治注入式攻击有比较明显的效果。
3.强迫使用参数化语句
如果在编写SQL语句的时候,用户输入的变量不是直接嵌入到SQL语句。而是通过参数来传递这个变量的话,那么就可以有效的防治SQL注入式攻击。也就是说,用户的输入绝对不能够直接被嵌入到SQL语句中。与此相反,用户的输入的内容必须进行过滤,或者使用参数化的语句来传递用户输入的变量。参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。采用这种措施,可以杜绝大部分的SQL注入式攻击。不过可惜的是,现在支持参数化语句的数据库引擎并不多。不过数据库工程师在开发产品的时候要尽量采用参数化语句。
从软件工具问题来讲:
最省事的方法,不想让自己的数据库受到伤害有一款强大的软件也不错,在这里推荐一款,One QASPRuntime Application Self-Protection。防SQL 注入、XSS(跨站脚本攻击)、敏感信息泄露、未验证的重定向和转发、非标准请求和已知漏洞扫描工具。
工作原理:

保护好你的数据库,让你的电脑数据不再发生意外~~~