天天看點

java.security.MessageDigest的使用(2),生成安全令牌!

時候,我們需要産生一個資料,這個資料儲存了使用者的資訊,但加密後仍然有可能被人使用,即便他人不确切的了解詳細資訊...

好比,我們在上網的時候,很多網頁都會有一個資訊,是否儲存登入資訊,以便下次可以直接登入而不必再次輸入賬戶,密碼等...而通常這樣需要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

繼續閱讀