java實現(xiàn)忘記密碼功能

最近項目中需要用到忘記密碼的功能,因此,寫了這篇博客進行記錄。
首先需要用戶點擊忘記密碼,輸入用戶名和郵箱,兩者可以匹配,則向郵箱中發(fā)送條鏈接。eg:

點擊此鏈接進行密碼修改,有效期一個小時www.abc.com?ha=2HwBjxyI4WDRBUwewvo8xioRXszig1tf1Vx4dSMa5wI

點擊此鏈接進行重置密碼,后臺接受到ha參數(shù)的值,并對其進行解析,通過則可以進行密碼修改。
下邊主要解釋如何加密這個ha參數(shù),這里使用到了Base64進行加密和解密。
這里利用了一個jar包:commons-codec-1.8.jar(可以從官網(wǎng)或者maven下載)

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.8</version>
</dependency>

加密和解密工具類如下:

package com.ocean.utils;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;

public class UrlUtils {
    private static final String KEY = "myoMwO6qPt&3AD";
    private static final Logger LOGGER = LoggerFactory.getLogger(UrlUtils.class);

    public static String enCryptAndEncode(String content) {
        try {
            byte[] sourceBytes = enCryptAndEncode(content, KEY);
            return Base64.encodeBase64URLSafeString(sourceBytes);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return content;
        }
    }

    /**
     * 加密函數(shù)
     * @param content 加密的內(nèi)容
     * @param strKey  密鑰
     * @return 返回二進制字符數(shù)組
     * @throws Exception
     */
    public static byte[] enCryptAndEncode(String content, String strKey) throws Exception {

        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128, new SecureRandom(strKey.getBytes()));

        SecretKey desKey = keyGenerator.generateKey();
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        return cipher.doFinal(content.getBytes("UTF-8"));
    }

    public static String deCryptAndDecode(String content) throws Exception {
        byte[] targetBytes = Base64.decodeBase64(content);
        return deCryptAndDecode(targetBytes, KEY);
    }


    /**
     * 解密函數(shù)
     * @param src    加密過的二進制字符數(shù)組
     * @param strKey 密鑰
     * @return
     * @throws Exception
     */
    public static String deCryptAndDecode(byte[] src, String strKey) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128, new SecureRandom(strKey.getBytes()));

        SecretKey desKey = keyGenerator.generateKey();
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        byte[] cByte = cipher.doFinal(src);
        return new String(cByte, "UTF-8");
    }
}

發(fā)送鏈接時,可以使用這個工具類,對參數(shù)進行加密和解密。我這個采用的方式是:對 用戶名+";"+郵箱+";"+時間戳 進行加密和解密
下面來一個測試類

    @Test
    public void test1() throws Exception{
        long endTimes = System.currentTimeMillis()+3600*1000;   //設(shè)置一小時有效時間。。
         String para = "admin"+";"+"20@qq.com"+";"+endTimes;
         System.out.println("原文"+para);
         String encode = UrlUtils.enCryptAndEncode(para);
         System.out.println("加密"+encode);  //http://www.cnblogs.com/haha12/p/4345070.html
         String old = UrlUtils.deCryptAndDecode(encode);
         System.out.println("解密:"+old);
         String[] split = old.split(";");
         for (String string : split) {
            System.out.println(string);
        }
    }
打印結(jié)果如下:
原文admin;20@qq.com;1541492725208
加密2HwBjxyI4WDRBUwewvo8xhcxtyeFhvB2tMG2W3QYwW0
解密:admin;20@qq.com;1541492725208
admin
20@qq.com
1541492725208

后臺可以通過拿到這個參數(shù)值,解密之后進行處理。例子如下:

    public String toResetPwd(){
        String ha = context.getParameter("ha");
        if(null!=ha){
            try {
                //這里拿到參數(shù),進行解密操作
                String decode = UrlUtils.deCryptAndDecode(ha);
                String[] split = decode .split(";");
                List<String> list = Arrays.asList(split);
                if(null!=list && list.size()>0){
                    String personname = (String)list.get(0);
                    String email = (String)list.get(1);
                    long entimes = Long.parseLong((String)list.get(2));
                    long curtime = System.currentTimeMillis();
                    if(entimes<=curtime){   //判斷有效期
                        context.setRequestAttribute("errorMsg", "當(dāng)前鏈接已失效,請重新 后去重置密碼鏈接!");
                    }else{
                        context.setRequestAttribute("personname", personname);
                        context.setRequestAttribute("email", email);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                context.setRequestAttribute("errorMsg", "鏈接無效!");
            }
        }
        return "SUCCESS";
    }

到這里,就可以結(jié)束了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,654評論 19 139
  • 文中首先解釋了加密解密的一些基礎(chǔ)知識和概念,然后通過一個加密通信過程的例子說明了加密算法的作用,以及數(shù)字證書的出現(xiàn)...
    納蘭三少閱讀 2,045評論 1 6
  • 大學(xué)畢業(yè)兩年,今年二十五六歲。 畢分季和畢婚季已經(jīng)過去很久很久了。 然后我們,要么結(jié)婚生子,要么在去往婚姻的路上,...
    念情笑笑閱讀 283評論 0 0
  • 1.灰子解字-前 前者, 不行而進也! 上為止, 下為舟也! 舟者, 行于水上, 可行千里也! 止者,是為停也! ...
    灰常出色閱讀 347評論 0 3

友情鏈接更多精彩內(nèi)容