時候,我們需要産生一個資料,這個資料儲存了使用者的資訊,但加密後仍然有可能被人使用,即便他人不确切的了解詳細資訊...
好比,我們在上網的時候,很多網頁都會有一個資訊,是否儲存登入資訊,以便下次可以直接登入而不必再次輸入賬戶,密碼等...而通常這樣需要cookie儲存使用者資訊,當然,這個資訊是加密資訊,且一般都加了時間戳等驗證資訊的...
登陸時,讀取cookie,解析cookie的資訊,以及如時間戳等附加資訊.如果沒有時間戳...那麼任何人隻要有這個cookie,複制cookie到他的電腦中,然後登陸相同的頁面,即便盜用者并不知道使用者的資訊是什麼,也能登陸...
是以,時間戳就類似我們所說的安全令牌.
方式,将使用者資訊md5加密後,再将時間戳md5加密,然後按照特定的處理,将加密後的使用者資訊以及時間戳,ip位址等資訊再次處理,加密後,生成cookie儲存用戶端...這樣就避免了前面所說的安全問題...
java.security.messagedigest,在建立安全令牌上,比md5更簡便.因為update方法!!!
view plaincopy to clipboardprint?
package cn.vicky.utils;
import java.security.messagedigest;
import java.security.nosuchalgorithmexception;
/**
* 令牌處理器
*
* @author vicky
* @emial [email protected]
*/
public class tokenprocessor {
private static tokenprocessor instance = new tokenprocessor();
private long previous;
protected tokenprocessor() {
}
public static tokenprocessor getinstance() {
return instance;
public synchronized string generatetoken(string msg, boolean timechange) {
try {
long current = system.currenttimemillis();
if (current == previous) current++;
previous = current;
messagedigest md = messagedigest.getinstance("md5");
md.update(msg.getbytes());
if (timechange) {
// byte now[] = (current+"").tostring().getbytes();
byte now[] = (new long(current)).tostring().getbytes();
md.update(now);
}
return tohex(md.digest());
} catch (nosuchalgorithmexception e) {
return null;
}
private string tohex(byte buffer[]) {
stringbuffer sb = new stringbuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++) {
sb.append(character.fordigit((buffer[i] & 240) >> 4, 16));
sb.append(character.fordigit(buffer[i] & 15, 16));
return sb.tostring();
}
package cn.vicky.utils;
import java.security.messagedigest;
import java.security.nosuchalgorithmexception;
/**
* 令牌處理器
*
* @author vicky
* @emial [email protected]
*/
public class tokenprocessor {
private static tokenprocessor instance = new tokenprocessor();
private long previous;
protected tokenprocessor() {
}
public static tokenprocessor getinstance() {
return instance;
public synchronized string generatetoken(string msg, boolean timechange) {
try {
long current = system.currenttimemillis();
if (current == previous) current++;
previous = current;
messagedigest md = messagedigest.getinstance("md5");
md.update(msg.getbytes());
if (timechange) {
// byte now[] = (current+"").tostring().getbytes();
byte now[] = (new long(current)).tostring().getbytes();
md.update(now);
}
return tohex(md.digest());
} catch (nosuchalgorithmexception e) {
return null;
}
private string tohex(byte buffer[]) {
stringbuffer sb = new stringbuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++) {
sb.append(character.fordigit((buffer[i] & 240) >> 4, 16));
sb.append(character.fordigit(buffer[i] & 15, 16));
return sb.tostring();
}
測試
@test
public void testgeneratetoken(){
string token = new tokenprocessor().generatetoken("vicky",true);
system.err.println(token);
string token2 = new tokenprocessor().generatetoken("vicky",false);
system.err.println(token2);
@test
public void testgeneratetoken(){
string token = new tokenprocessor().generatetoken("vicky",true);
system.err.println(token);
string token2 = new tokenprocessor().generatetoken("vicky",false);
system.err.println(token2);
執行後列印:
69ff8ae72232da59a613ecc830ed7c7a
020c290593cef84aeac4ea2c269d326d
再次執行列印:
d8e38257652deaa76de81c8225801482
可見,第1列印的資料,是一直變換的.因為他加入了時間戳
而第2條列印的資料卻是不變的,因為他隻是簡單的md5加密
這樣的安全令牌在很多大型架構中都會涉及,比如說頂頂大名的struts.這裡,我以servlet為執行個體,向request請求加入安全令牌!
package cn.vicky.struts.util;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpsession;
* @email [email protected]
public synchronized boolean istokenvalid(httpservletrequest request) {
return istokenvalid(request, false);
public synchronized boolean istokenvalid(httpservletrequest request,
boolean reset) {
httpsession session = request.getsession(false);
if (session == null
return false;
string saved = (string) session
.getattribute("cn.vicky.struts.action.token");
if (saved == null)
if (reset)
resettoken(request);
string token = request
.getparameter("cn.vicky.struts.taglib.html.token");
if (token == null)
else
return saved.equals(token);
public synchronized void resettoken(httpservletrequest request) {
if (session == null) {
return;
} else {
session.removeattribute("cn.vicky.struts.action.token");
public synchronized void savetoken(httpservletrequest request) {
httpsession session = request.getsession();
string token = generatetoken(request);
if (token != null)
session.setattribute("cn.vicky.struts.action.token", token);
public synchronized string generatetoken(httpservletrequest request) {
return generatetoken(session.getid());
public synchronized string generatetoken(string id) {
if (current == previous)
current++;
previous = current;
// byte now[] = (current+"").tostring().getbytes();
byte now[] = (new long(current)).tostring().getbytes();
md.update(id.getbytes());
md.update(now);
system.out.println(md.digest().length);
本文來自csdn部落格,轉載請标明出處:http://blog.csdn.net/eclipser1987/archive/2010/01/08/5159106.aspx