做綠色軟件的網(wǎng)站知乎百度關(guān)鍵詞推廣費用
業(yè)務(wù)來源:
? ? ? ?最近工作中,領(lǐng)導(dǎo)要求給別的項目組的小伙伴提供幾個接口,要求對接口的參數(shù)進(jìn)行解密操作,然后對返回的數(shù)據(jù)進(jìn)行加密操作。
? ? ? ?這時我想到了AES??
? ? ? ?AES?是對稱加密算法,優(yōu)點:加密速度快;缺點:如果秘鑰丟失,就容易解密密文,安全性相對比較差。
代碼案例:
請求參數(shù)格式:
{"appId":?"queryLectureListByPage","data":?"eIVh49T2zKQrtcrhVi6BXcXljN4XFlZc9csQiyayIE1eYeIatVNc9gOTL6HHYj29arBEV3TXMVnQxGIR2EHMfICQz+Aq5ldGk0ys13Rgiqk="
}
響應(yīng)的參數(shù)格式:
{"code":?200,"message":?"ok","data":?"eHDl88EzrjfZzA179EN6s1dUPs10bWpSWRo2skyQf1+eO6x66ypDnVXoyB5wr6T62lmfVdwa3oK0ZFqnOzd3SW/DE6UaMPZtJovzFTpjxbzvnuwO3v9b3vEsA2nOUQEjEqbpzBrzEClNtL2tkSuoA7oJkTiH3ec6otwFFJZGbV93JW9+xvFkG3TObHIO6fdqlgNIDGbgs7TnwStc64suuH+H7Bt25pCggCq6yVv+Zx69/0Zprvu5s7Dma8NYy/N69cfWgj+06Ik5DXcJlzlZXKQLwwQHiHtleIum2dSF3HWE7ck212n/zn1WVVpGUFnevYCr7Gx/lHbkh/hIOifl8sDpkaISP2tO4kXDi1neUyCnrM7437rf/ZhLPBANkkIO40cZcjEGdrMNswAfZ6XxkBTBq3BMpnjulUbSPZXA6xwwdiaORv1Jx9yxpVBRuw5D4FHby+VPRAh3WP2VMptpzXYeJGBJXU/KvODrKy+tDb8Iq/PUESzECrrYVc/QwWVeBmNKOFyCtXTB486QWqUGbFvoWHnQUUh/taM8/GOYglWzCtziDntRxum2qruxuq23fnNknKGi3wJBzBSZj8kWw0NUx7RIaZcoqwbzmYx4H6h9D28ViAv/y4/nQGxKho3nlW5EVuk6+yQLadc1DSp4Ug=="
}
生成密鑰:
package com.ly.cloud.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.druid.util.Base64;
import org.apache.commons.codec.binary.Hex;public class AESUtils {private static final String AES = "AES";private static final String UTF8 = "UTF-8";private static final String CIPHERALGORITHM = "AES/ECB/PKCS5Padding";private static final String Key = "9!#95hsup*&$1zq7";public static void main(String[] args) throws IOException {// wqkjejqwkejqwk 可隨便輸入字符串,生成對應(yīng)的密鑰String wqkjejqwkejqwk = encrypts("wqkjejqwkejqwk");System.out.println(wqkjejqwkejqwk);}/*** 生成base 64 作為AES加密后的密鑰*/public static String encrypts(String content) {try {byte[] encodeFormat = Key.getBytes();SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);// Cipher對象實際完成加密操作Cipher cipher = Cipher.getInstance(CIPHERALGORITHM);// 加密內(nèi)容進(jìn)行編碼byte[] byteContent = content.getBytes(UTF8);// 用密匙初始化Cipher對象cipher.init(Cipher.ENCRYPT_MODE, key);// 正式執(zhí)行加密操作byte[] result = cipher.doFinal(byteContent);return Hex.encodeHexString(result);} catch (Exception e) {e.printStackTrace();return null;}}}
思路:
通過傳入的appId然后去數(shù)據(jù)庫中查詢到對應(yīng)的 唯一密鑰。然后根據(jù)唯一密鑰進(jìn)行解析密文。然后轉(zhuǎn)成將密文轉(zhuǎn)成 我們需要的參數(shù)對象。
核心代碼:
AES加密解密工具類:
package com.ly.cloud.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.druid.util.Base64;
import org.apache.commons.codec.binary.Hex;public class AESUtils {private static final String AES = "AES";private static final String UTF8 = "UTF-8";private static final String CIPHERALGORITHM = "AES/ECB/PKCS5Padding";private static final String Key = "9!#95hsup*&$1zq7";/*** AES加密+Base64轉(zhuǎn)碼* * @param data 明文(16進(jìn)制)* @param key 密鑰* @return*/public static String encrypt(String data, String key) {byte[] keyb = null;keyb = Base64.base64ToByteArray(key);SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");Cipher cipher = null;try {cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {e.printStackTrace();}try {cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);} catch (InvalidKeyException e) {e.printStackTrace();}byte[] bjiamihou = null;String miwen = "";try {bjiamihou = cipher.doFinal(data.getBytes("utf-8"));// byte加密后miwen = Base64.byteArrayToBase64(bjiamihou);// 密文用base64加密} catch (IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return miwen;}/*** Base64解碼 + AES解碼* * @param data 密文 (16進(jìn)制)* @param key 密鑰* @return*/public static String decrypt(String data, String key){byte[] keyb = null;keyb = Base64.base64ToByteArray(key);byte[] miwen = Base64.base64ToByteArray(data);SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");Cipher cipher = null;try {cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {e.printStackTrace();}try {cipher.init(Cipher.DECRYPT_MODE, sKeySpec);} catch (InvalidKeyException e) {e.printStackTrace();}byte[] bjiemihou = null;String mingwen = "";try {bjiemihou = cipher.doFinal(miwen);// byte加密后mingwen = new String(bjiemihou,"utf-8");} catch (IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return mingwen;}public static void main(String[] args) throws IOException {String name = "{\"userId\":\"179135\",\"keyword\":\"講座副標(biāo)題\",\"pageNum\":\"1\",\"pageSize\":\"10\"}";
// String encrypt = encrypt(name, "qVkn2qNkkyAAF8PjQL/7GQ==");
// String name = "{\"userId\":\"179135\",\"pageNum\":\"1\",\"pageSize\":\"20\"}";// String name1 = "{\"userId\":\"179135\",\"organizerId\":\"02020\"}";String name1 = "{\"pageNum\":\"1\",\"pageSize\":\"20\"}";String encrypt = encrypt(name, "8c5e186c9de8e9a628234522a794f45b0f");System.out.println(encrypt);System.out.println("---------");System.out.println(decrypt(encrypt,"8c5e186c9de8e9a628234522a794f45b0f"));String wqkjejqwkejqwk = encrypts("wqkjejqwkererjqwk");System.out.println(wqkjejqwkererjqwk);}/*** 生成base 64 作為AES加密后的密鑰*/public static String encrypts(String content) {try {byte[] encodeFormat = Key.getBytes();SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);// Cipher對象實際完成加密操作Cipher cipher = Cipher.getInstance(CIPHERALGORITHM);// 加密內(nèi)容進(jìn)行編碼byte[] byteContent = content.getBytes(UTF8);// 用密匙初始化Cipher對象cipher.init(Cipher.ENCRYPT_MODE, key);// 正式執(zhí)行加密操作byte[] result = cipher.doFinal(byteContent);return Hex.encodeHexString(result);} catch (Exception e) {e.printStackTrace();return null;}}// 加密 public static String dataToAES(String password,String data){String hexStr = encrypt(data, password);return hexStr;}// 解密public static String AESToData(String password, String data){return decrypt(data, password);}}
業(yè)務(wù)層核心代碼:?
@Overridepublic String organizerList(LectureEncryptDto encrypt) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {//獲取appid 對應(yīng)的key值String key = checkParam(encrypt);// 解密參數(shù) 根據(jù)傳入不同的 對象返回不同的對象MySubscribeDto subscribe = returnObject(MySubscribeDto.class, key, encrypt);//校驗解密后參數(shù)是否為空checkPageParam(subscribe, "2");Page<MySubscribe> page = new Page<>(subscribe.getPageNum(), subscribe.getPageSize());PageDto<MySubscribe> pageDto = new PageDto<>();IPage<MySubscribe> pageData = lectureMapper.organizerList(page, subscribe.getUserId());pageDto.setTotal(pageData.getTotal());pageDto.setPages(pageData.getPages());pageDto.setPageSize(subscribe.getPageSize());pageDto.setPageNum(subscribe.getPageNum());pageDto.setList(pageData.getRecords());//加密String json = JSONUtil.toJsonStr(pageDto);return AESUtils.dataToAES(key, json);}/*** 根據(jù)傳入的不同的對象,將他進(jìn)行解密。然后返回*/public static <T> T returnObject(Class<T> clazz, String key, LectureEncryptDto dto) {Gson gson = new Gson();String decryptedData = AESUtils.AESToData(key, dto.getData());if (StrUtil.isEmpty(decryptedData)) {throw new BusinessException("appId生成的data密鑰有誤");}return gson.fromJson(decryptedData, clazz);}/*** 檢查appID 是否有效*/public String checkParam(LectureEncryptDto dto) {// 根據(jù)他傳的appid 去數(shù)據(jù)庫里取出appid 對應(yīng)的 key值,String key = lectureMapper.getAppIdKey(dto.getAppId());if (StrUtil.isEmpty(key)) {throw new BusinessException("appId有誤,請重新輸入");}return key;}/*** 檢查分頁-以及其它所需參數(shù)是否為空*/public static void checkPageParam(Object objects, String key) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class<?> clazz = objects.getClass();Method getPageSizeMethod = clazz.getMethod("getPageSize");Method getPageNumMethod = clazz.getMethod("getPageNum");Integer pageSize = (Integer) getPageSizeMethod.invoke(objects);Integer pageNum = (Integer) getPageNumMethod.invoke(objects);if (pageSize == null || pageNum == null) {throw new BusinessException("頁碼不能為空");}// 根據(jù)key設(shè)置相應(yīng)的屬性switch (key) {case "1":break;case "2":Method userIdMethod = clazz.getMethod("getUserId");if (StrUtil.isEmpty((String) userIdMethod.invoke(objects))) {throw new BusinessException("學(xué)工號不能為空");}break;case "3":Method user = clazz.getMethod("getUserId");Method getId = clazz.getMethod("getOrganizerId");if (StrUtil.isEmpty((String) user.invoke(objects)) && StrUtil.isEmpty((String) getId.invoke(objects))) {throw new BusinessException("學(xué)工號或主辦單位ID不能為空");}}}