關於AES加密

用戶登錄密碼加密我們常見的有MD5,RSA,AES等。前段時間項目經理讓我搞個登錄加密,我用的是AES加密方法,前端加密,後臺解密。話不多說,主要總結以下幾點:

  1,前臺加密的祕鑰key和iv跟後臺解密用的祕鑰要一致;

  2,解決登錄成功後頁面回退到登錄頁面時無法登錄的問題(jsp頁面上有註釋);

登錄頁面
<%@page import="com.dq.entity.TgUser"%>
<%@ page language="java" contentType="text/html;charset=gb2312" %>
<%@ page import="com.datais.base.*, com.datais.web.*, com.dq.*, com.dq.tools.*,com.dq.service.*,com.dq.service.normal.*,com.dq.tools.result.*,com.project.AesUtil" %>


<%
	HttpInput input = new HttpInput(request);
	String useraction = input.getString("useraction");
	String userid= input.getString("userid");
	String password= input.getString("password"); 
	System.out.println(password);
	boolean openpage = true;
	StringBuffer msg = new StringBuffer();
	//調用AesUtil裏的解密方法,將解密後的賬號密碼傳到驗證賬號密碼的TgUser方法內
	AesUtil  aes = new AesUtil();
	//Key,IV都是寫死的固定值,因此直接定義的全局變量,並Getters一下,這樣調用的時候可以直接獲取到這兩個定值
	String decryptedAct = aes.decrypt(userid,aes.getKey(), aes.getIv());
	String decryptedPwd = aes.decrypt(password, aes.getKey(), aes.getIv());
	String decryptedUserAct = aes.decrypt(useraction, aes.getKey(), aes.getIv());
  String userip;
  userip = request.getHeader("x-forwarded-for");  
  if(userip == null || userip.length() == 0 || "unknown".equalsIgnoreCase(userip)) {  
      userip = request.getHeader("Proxy-Client-IP");  
  }
  if(userip == null || userip.length() == 0 || "unknown".equalsIgnoreCase(userip)) {  
      userip = request.getHeader("WL-Proxy-Client-IP");  
  }
  if(userip == null || userip.length() == 0 || "unknown".equalsIgnoreCase(userip)) {  
      userip = request.getRemoteAddr();  
  }

	if ("logon".equals(decryptedUserAct)) {
		TgUser user = new TgUser(decryptedAct, decryptedPwd, userip);
		if (user.logon(msg)) {
			session.setAttribute(UserSession.ID, user);
			System.out.println(user.toString());
			if(Integer.parseInt(user.getParam("czdeptlevel")) < 3 && user.getParam("roles").equals("SWJJS01")){
				response.sendRedirect(Constant.MAIN_URL+"?objectid="+Constant.MENU_ID);
			}else if(user.getParam("roles").equals("SWJJS00")){
				response.sendRedirect(Constant.MAIN_URL+"?objectid="+Constant.MENU_ID);
			}else{
				response.sendRedirect(Constant.MAIN_URL+"?objectid="+Constant.MENU_ID);
			}
			LogFiles lf = new LogFiles();
			ReturnMsg rm = new ReturnMsg();
			rm = lf.Isexists();
			if(rm.isSuccess()){
				rm  = lf.Logon(user,"1");
			}
		}
	}

	if (openpage) {
		if ("logoff".equals(decryptedUserAct)) {
			UserSession user = (UserSession)session.getAttribute(UserSession.ID);
			if (user!=null){
			  user.logoff(msg, session);
				LogFiles lfs = new LogFiles();
				ReturnMsg rm = new ReturnMsg();
				rm = lfs.Isexists();
				if(rm.isSuccess()){
					rm  = lfs.Logon(user,"3");
				}
			}
		}
	}
%>
<!DOCTYPE html>
<html>
<head>
	<title>數據質量管理平臺</title>
	<link rel="stylesheet" href="project/style/login.css">
	<script type="text/javascript" src="project/js/aesaes.js"></script>
<script type="text/javascript">
function encodeAesString(data,key,iv){
	var key  = CryptoJS.enc.Utf8.parse(key); 
	var iv   = CryptoJS.enc.Utf8.parse(iv); 
	var encrypted =CryptoJS.AES.encrypt(data,key,{
		iv:iv, 
		mode:CryptoJS.mode.CBC,
		padding:CryptoJS.pad.Pkcs7 
	});
	//返回的是base64格式的密文	
	return encrypted;
}
 
// encrypted 爲是base64格式的密文
function decodeAesString(encrypted,key,iv){
	var key  = CryptoJS.enc.Utf8.parse(key);
	var iv   = CryptoJS.enc.Utf8.parse(iv);
	var decrypted =CryptoJS.AES.decrypt(encrypted,key,{
		iv:iv,
		mode:CryptoJS.mode.CBC,
		padding:CryptoJS.pad.Pkcs7
	});
	return decrypted.toString(CryptoJS.enc.Utf8);
}
 
// 加密
function submitForm(){	
	 var theForm = document.forms[0]; 
	 if(theForm.userid.value !='' && theForm.password.value !=''){ 
		if(parent!=null){
			theForm.target = "_parent";
			var key  = 'abcdef0123456789';  // 密鑰 長度16
			var iv   = 'abcdef0123456789';  // 密鑰 長度16
			var Name = theForm.useraction.value;
			theForm.useraction.value = encodeAesString(Name,key,iv);
			theForm.password.value = encodeAesString(document.getElementById("password1").value,key,iv);//根據<input>的ID獲取value
			theForm.userid.value = encodeAesString(document.getElementById("userid1").value,key,iv);
			//alert("useraction加密後"+theForm.useraction.value);
			//theForm.password.value = decodeAesString(theForm.password.value,key,iv);
			//alert("加密後"+theForm.password.value);
			theForm.submit();
		}
	  }
}

</script>
</head>
<body>
<form name="logic" method="post" action="login.jsp">
     <!-- 解決登錄時輸入框內賬號密碼變爲加密後的賬號密碼導致返回時無法繼續登錄的問題
	    form.submit()方法都是通過<input>輸入框的name來獲取value,所以定義一個隱藏的輸入框,將加密後的賬號密碼放入這個框裏,這樣原先的輸入框的內容就不會變
		提交時也是提交隱藏輸入框內的值,當頁面回退時顯現的輸入框內的值還是我們之前輸入的值-->
	<input type="hidden" name="useraction" value="logon" />
	<input type="hidden" name="userid" value=" " />
	<input type="hidden" name="password" value=" " />
	<div class="container wrap">
		<h1 class="logo">數據質量管理平臺</h1>
		<div class="col-sm-8 col-md-5 main_content">
			<div class="loginTit">用戶登錄</div>					
			<div class="form-group mg-t20">
				<i class="icon-user icon_font"></i>
				<input type="text" class="login_input" id="userid1" placeholder="請輸入用戶名" />
			</div>
			<div class="form-group mg-t20">
				<i class="icon-manager icon_font"></i>
				<input type="password" class="login_input" id="password1"  value="121314" placeholder="請輸入密碼" /> 
			</div>	                    
			<button style="submit" class="login_btn" onclick="submitForm()" >登 錄</button>
			<div class="form-group msg_error">
				<%= msg.toString() %> 
			</div>	   
		</div> 
	</div>  
</form>
</body>
</html>

後臺解密java類
package com.project;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;


public class AesUtil {
	public static  String key ="abcdef0123456789";
	public  static  String iv ="abcdef0123456789";
	public static String getKey() {
		return key;
	}
	
	public static String getIv() {
		return iv;
	}
	
   /**
    * 加密返回的數據轉換成 String 類型
    * @param content 明文
    * @param key 祕鑰
    * @param iv 初始化向量是16位長度的字符串
    * @return
    * @throws Exception
    */
   public static String encrypt(String content, String key, String iv) throws Exception {
       // 將返回的加密過的 byte[] 轉換成Base64編碼字符串  !!!!很關鍵
       return base64ToString(AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes()));
   }
   /**
    * 將解密返回的數據轉換成 String 類型
    * @param content Base64編碼的密文
    * @param key 祕鑰
    * @param iv 初始化向量是16位長度的字符串
    * @return
    * @throws Exception
    */
   public static String decrypt(String content, String key, String iv) throws Exception {
       // stringToBase64() 將 Base64編碼的字符串轉換成 byte[]  !!!與base64ToString()配套使用
       return new String(AES_CBC_Decrypt(stringToBase64(content), key.getBytes(), iv.getBytes()));
   }

   private static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes, byte[] iv){
       try {
           SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
           cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv));
           byte[] result = cipher.doFinal(content);
           return result;
       } catch (Exception e) {
           System.out.println("exception:"+e.toString());
       }
       return null;
   }

   private static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes, byte[] iv){
       try {
           SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
           cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
           byte[] result = cipher.doFinal(content);
           return result;
       } catch (Exception e) {
           System.out.println("exception:"+e.toString());
       }
       return null;
   }

   /**
    * 字符串裝換成 Base64
    */

   public static byte[] stringToBase64(String key) throws Exception {
       return Base64.decodeBase64(key.getBytes());
   }

   /**
    * Base64裝換成字符串
    */
   public static String base64ToString(byte[] key) throws Exception {
       return new Base64().encodeToString(key);
   }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章