聲明:如下記錄了本人實驗性地探索過程,不表明正確,請謹慎食用。
也歡迎提出各類批評建議,幫助我改正錯誤。謝謝!javascript
註冊時在註冊的jsp頁面使用js函數進行合法性驗證(包括空值、兩次輸入密碼是否相同等),並設置爲onclick或onsubmit觸發。
具體觸發順序以下
1) onclick: Y();php
2) onsubmit: X();css
3) submit();html
在表單submit以前會調用onsubmit(),注意調用時爲onsubmit="return CheckPost();"
若是直接寫"CheckPost()"則沒法生效。若是返回false則不會調用submit,返回true纔會執行到submit。前端
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <script language="javascript" type="text/javascript"> function check() { if (document.sign.username.value==""){ alert("請輸入登陸帳號!"); return false; } if (document.sign.password1.value==""){ alert("請輸入登陸密碼!"); return false; } if (document.sign.password2.value==""){ alert("請輸入重複密碼!"); return false; } var pd1=document.sign.password1.value; var pd2=document.sign.password2.value; if (pd1!=pd2){ alert("對不起!重複密碼不等於登陸密碼"); return false; } return true; } </script> <title>註冊</title> </head> <body> <form action="Signup" method="post" name ="sign" onSubmit="return check()"> <input type="hidden" name="action" value="signup"/> 用戶名:<input type="text" name="username" /> 密碼:<input type="password" name="password1" /> 確認密碼:<input type="password" name="password2" /> <input type="submit" value="註冊" /> </form> </body> </html>
點擊提交按鈕時觸發,此時須要在函數中手動submit提交。java
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <script language="javascript" type="text/javascript"> function check() { if (document.sign.username.value==""){ alert("請輸入登陸帳號!"); return false; } if (document.sign.password1.value==""){ alert("請輸入登陸密碼!"); return false; } if (document.sign.password2.value==""){ alert("請輸入重複密碼!"); return false; } var pd1=document.sign.password1.value; var pd2=document.sign.password2.value; if (pd1!=pd2){ alert("對不起!重複密碼不等於登陸密碼"); return false; } document.sign.submit(); return true; } </script> <title>註冊</title> </head> <body> <form action="Signup" method="post" name ="sign" > <input type="hidden" name="action" value="signup"/> 用戶名:<input type="text" name="username" /> 密碼:<input type="password" name="password1" /> 確認密碼:<input type="password" name="password2" /> <input type="button" value="註冊" onClick="check()" /> </form> </body> </html>
在用戶登陸以及註冊時,有必要對數據進行加密。任何語言最終都會造成html,事實上前端也只能處理html,css,js代碼,其餘如java,php,c#都是在後端工做的,在html經過web服務器發送給訪問者的時候已經脫離了後端的控制。所以前端的惟一加密手段就是js,可是js是明文的,也就是說你的加密過程是透明的,天然徹底沒有破解難度。固然,md5之類的單向加密依然沒法破解,問題是後端拿到單向加密的數據徹底沒用,由於它推導不出原始數據是什麼。因此,要安全就用https。
設置Tomcat的HTTPS配置方法以下:
① keytool工具生成證書
打開 JDK 自帶的 keytool 目錄。mysql
按住 Shift 鍵,同時右鍵點擊空白處。git
此時,進入cmd窗口。輸入下面命令。web
keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "F:\tomcat.keystore"
接着會讓你填寫一些基本信息。算法
下面簡要介紹一下。
密鑰庫口令:123456(這個密碼很是重要)
名字與姓氏:localhost(之後訪問的域名或IP地址,很是重要,證書和域名或IP綁定)
組織單位名稱:anything(隨便填)
組織名稱:anything(隨便填)
城市:anything(隨便填)
省市自治區:anything(隨便填)
國家地區代碼:anything(隨便填)
② 應用證書到Tomcat
打開 Tomcat 配置文件 confserver.xml。
取消註釋,並添加兩個屬性 keystoreFile,keystorePass。
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="F:/tomcat.keystore" keystorePass="123456" />
後臺得到數據(用戶名和密碼)後,須要對密碼數據進行加密。因爲username在mysql中被設置成了unique的,因此並不適合加密存入。這裏只對密碼進行加密。
加密方法爲:
加密工具類:
import java.security.MessageDigest; public class MD5Util { public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = s.getBytes(); // 得到MD5摘要算法的 MessageDigest 對象 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 使用指定的字節更新摘要 mdInst.update(btInput); // 得到密文 byte[] md = mdInst.digest(); // 把密文轉換成十六進制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } }
加密過程:
String salt = MD5Util.MD5(username); if(username.length()%2==0) password = password+salt; else password = salt+password; password = MD5Util.MD5(password);
經過unique的username經過MD5加密做爲每一個user獨有的salt,再將password與salt鏈接後再MD5加密。MD5算法hash碰撞的可能性很小,所以基本能夠保證salt和password加密後都是獨一無二的,防止黑客用彩虹表爆表。
不建議將salt與用戶信息存在一塊兒,防止數據庫被黑後黑客能夠輕易破解用戶密碼。
存儲結果以下:
能夠看到密碼已經被加密。
若是你的SQL語句是相似where id={$id}這種形式,數據庫裏全部的id都是數字,那麼就應該在SQL被執行前,檢查確保變量id是int類型;若是是接受郵箱,那就應該檢查並嚴格確保變量必定是郵箱的格式,其餘的類型好比日期、時間等也是一個道理。總結起來:只要是有固定格式的變量,在SQL語句執行前,應該嚴格按照固定格式去檢查,確保變量是咱們預想的格式,這樣很大程度上能夠避免SQL注入攻擊。
使用PreparedStatement代替Statement是最有效也是最簡單的防止SQL注入的方式。
正如上面所說,對用戶數據進行加密是一個必要的手段。雖然說不能徹底防止SQL注入攻擊,可是能增大黑客暴力破解的難度。
一、不要隨意開啓生產環境中Webserver的錯誤顯示(避免1=1 1=2刺探漏洞以及爆字段)
二、永遠不要信任來自用戶端的變量輸入,有固定格式的變量必定要嚴格檢查對應的格式,沒有固定格式的變量須要對引號等特殊字符進行必要的過濾轉義。
三、使用預編譯綁定變量的SQL語句。
四、作好數據庫賬號權限管理。
五、嚴格加密處理用戶的機密信息。
原來是用戶表用MyISAM 帖子表用InnoDB提升併發性。
咱們將用戶id、用戶名、密碼存在一張表上,同時要確保id和用戶名是惟一的,這裏我將id做爲主鍵索引,用戶名做爲惟一索引。選擇MyISAM存儲引擎,有如下緣由:
理論上也能夠把用戶名做爲主鍵。但不推薦,理由大概有:
主題帖包括如下字段:
id(主鍵索引) title(標題) cont(內容) pdata(發帖時間) user(做者)isleaf
回覆貼包括如下字段:
id pid(父貼) rootid(主題帖id,創建索引) title cont(內容) pdata(發帖時間) user(做者)isleaf
主題帖存儲引擎使用MyISAM,有如下緣由:
回覆帖存儲引擎使用InnoDB,有如下緣由:
<script type="text/javascript"> var url = "<%=url%>"; delayURL(url); </script>
<span id="time" style="background:red">3</span>秒鐘後跳轉,或者點擊下面跳轉。 <script language="javascript" type="text/javascript"> function delayURL(url){//每隔一秒遞歸調用一次該函數,刷新秒數,直到秒數小於0跳轉 var delay = document.getElementById("time").innerHTML;//得到目前秒數 if (delay>0){ delay--; document.getElementById("time").innerHTML = delay }else{ window.top.location.href= url; } setTimeout("delayURL('"+url+"')",1000);//每隔一秒,調用一次delayURL } </script>