Commit 9b3bcdfd authored by 王向伟's avatar 王向伟

加解密演示示例

parent a52cdcfa
package cn.quantgroup.cashloanflowboss.api.encrypt;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.utils.AesUtil;
import cn.quantgroup.cashloanflowboss.utils.Md5Util;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Wang Xiangwei
* @version 2020/7/9
*/
@RestController
public class EncryptController {
String md5Key = "qEAxMJBv";
String aesKey = "sxD8KO79EDK0N0AJ";
@GetMapping("/encrypt")
public Result<StandardResult> encBizData(String bizData){
StandardResponse response = new StandardResponse();
response.setBizData(bizData);
response.setSign(Md5Util.build(bizData+md5Key));
StandardResult result = new StandardResult();
result.setResponse(response);
String responseStr = AesUtil.encryptAndBase64Encode(response.toJSON(), aesKey);
result.setEncResponseStr(responseStr);
return Result.buildSuccess(result);
}
@GetMapping("decrypt")
public Result<StandardResponse> decrypt(String responseStr){
String result = AesUtil.decryptAfterBase64Decode(responseStr, aesKey);
StandardResponse response = (new Gson()).fromJson(result, StandardResponse.class);
return Result.buildSuccess(response);
}
}
package cn.quantgroup.cashloanflowboss.api.encrypt;
import com.google.gson.Gson;
import lombok.Getter;
import lombok.Setter;
/**
* @author Wang Xiangwei
* @version 2020/7/9
*/
@Setter
@Getter
public class StandardResponse {
/**
* md5签名
*/
private String sign;
/**
* 业务数据json串(StandardResponse)
*/
private String bizData;
public String toJSON() {
return (new Gson()).toJson(this);
}
}
package cn.quantgroup.cashloanflowboss.api.encrypt;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/7/9
*/
@Data
public class StandardResult {
private StandardResponse response;
private String encResponseStr;
}
package cn.quantgroup.cashloanflowboss.utils;
/**
* Created by liqing on 2017/8/8 0008.
* aesKey密钥类型
*/
public enum AESKeyType {
plain("普通字符串"),base64("base64编码字符串");
private String text;
private AESKeyType(String text){
this.text = text;
}
}
package cn.quantgroup.cashloanflowboss.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
/**
* AES编码器工具
* 使用AES加密解密 AES-128-ECB加密
*
* @author chenkai
* @date 2016-11-5
*/
public class AesUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(AesUtil.class);
/**
* KEY算法
*/
private static final String KEY_ALGORITHM = "AES";
static String CHARSET = "UTF-8";
/**
* 加密算法
* "/算法/模式/补码方式"
*/
public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* KEY长度
*/
private static final int KEY_SIZE = 128;
public static void main(String[] args) {
try {
String key = getKeyStr();
} catch (Exception e) {
LOGGER.error("e={}", ExceptionUtils.getStackTrace(e));
}
}
/**
* 获取密钥 - Base64
*
* @return
* @throws Exception
*/
public static String getKeyStr() throws Exception {
return Base64.encodeBase64String(getKey().getEncoded());
}
/**
* 获取密钥
*
* @return
* @throws Exception
*/
public static Key getKey() throws Exception {
// 实例化
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
// AES 要求密钥长度为128位、192位或256位
kg.init(KEY_SIZE);
// 生成密钥
SecretKey secretKey = kg.generateKey();
return secretKey;
}
/**
* 数据加密
*
* @param data 待加密的数据
* @param key 加密使用的KEY
* @return 加密之后的数据
*/
public static String encryptAndBase64Encode(String data, String key) {
try {
return encryptAndBase64Encode(data.getBytes(CHARSET), key);
} catch (Exception e) {
LOGGER.error("AES加密报错,error={}", e);
return null;
}
}
/**
* 加密后base64编码,指定algorithm
*
* @param data
* @param key
* @param algorithm
* @return
*/
public static String encryptAndBase64Encode(String data, String key, String algorithm, AESKeyType aesKeyType) {
try {
return encryptAndBase64Encode(data.getBytes(CHARSET), key, algorithm, aesKeyType);
} catch (Exception e) {
LOGGER.error("AES加密报错,error={}", e);
return null;
}
}
/**
* 对字节数组加密
*
* @param data
* @param key
* @return
*/
public static String encryptAndBase64Encode(byte[] data, String key) {
try {
if (StringUtils.isBlank(key)) {
LOGGER.error("AES Key为空");
return null;
}
return doEncryptAndBase64Encode(data, key, CIPHER_ALGORITHM, AESKeyType.plain);
} catch (Exception ex) {
LOGGER.error("AES加密报错,error={}", ex);
return null;
}
}
/**
* 对字节数组加密,指定algorithm
*
* @param data
* @param key
* @return
*/
public static String encryptAndBase64Encode(byte[] data, String key, String algorithm, AESKeyType aesKeyType) {
try {
if (StringUtils.isBlank(key)) {
LOGGER.error("AES Key为空");
return null;
}
if (StringUtils.isBlank(algorithm)) {
LOGGER.error("AES 算法为空");
return null;
}
return doEncryptAndBase64Encode(data, key, algorithm, aesKeyType);
} catch (Exception ex) {
LOGGER.error("AES加密报错,error={}", ex);
return null;
}
}
/**
* 执行加密和base64编码
*
* @param data
* @param key
* @param algorithm
* @param aesKeyType
* @return
* @throws Exception
*/
private static String doEncryptAndBase64Encode(byte[] data, String key, String algorithm, AESKeyType aesKeyType) throws Exception {
algorithm = StringUtils.isBlank(algorithm) ? CIPHER_ALGORITHM : algorithm;
byte[] raw = toKey(key, aesKeyType);
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(data);
return new Base64().encodeToString(encrypted);
}
/**
* 数据解密,返回字符串
*
* @param data 待解密的数据
* @param key 解密使用的KEY
* @return 解密之后的数据
*/
public static String decryptAfterBase64Decode(String data, String key) {
try {
byte[] bytes = decryptAfterBase64DecodeToByte(data, key);
if (bytes != null && bytes.length > 0) {
return new String(bytes, CHARSET);
}
} catch (Exception e) {
LOGGER.error("AES解密报错,error={}", e);
}
return null;
}
/**
* base64解码后解密,指定algorithm
*
* @param data
* @param key
* @param algorithm
* @return
*/
public static String decryptAfterBase64Decode(String data, String key, String algorithm, AESKeyType aesKeyType) {
try {
byte[] bytes = decryptAfterBase64DecodeToByte(data, key, algorithm, aesKeyType);
if (bytes != null && bytes.length > 0) {
return new String(bytes, CHARSET);
}
} catch (Exception e) {
LOGGER.error("AES解密报错,error={}", e);
}
return null;
}
/**
* 数据解密,返回字节数据
*
* @param data
* @param key
* @return
*/
public static byte[] decryptAfterBase64DecodeToByte(String data, String key) {
try {
if (StringUtils.isBlank(key)) {
LOGGER.error("AES Key为空");
return null;
}
return doDecryptAfterBase64DecodeToBtype(data, key, CIPHER_ALGORITHM, AESKeyType.plain);
} catch (Exception ex) {
LOGGER.error("AES解密报错:" + ex.toString());
return null;
}
}
/**
* base64解码后解密,返回字节数组,指定算法
*
* @param data
* @param key
* @param algorithm
* @return
*/
public static byte[] decryptAfterBase64DecodeToByte(String data, String key, String algorithm, AESKeyType aesKeyType) {
try {
if (StringUtils.isBlank(key)) {
LOGGER.error("AES Key为空");
return null;
}
if (StringUtils.isBlank(algorithm)) {
LOGGER.error("AES 算法为空");
return null;
}
return doDecryptAfterBase64DecodeToBtype(data, key, algorithm, aesKeyType);
} catch (Exception ex) {
LOGGER.error("AES解密报错:" + ex.toString());
return null;
}
}
/**
* 执行base64解码后解密
*
* @param data
* @param key
* @param algorithm
* @param aesKeyType
* @return
* @throws Exception
*/
private static byte[] doDecryptAfterBase64DecodeToBtype(String data, String key, String algorithm, AESKeyType aesKeyType) throws Exception {
algorithm = StringUtils.isBlank(algorithm) ? CIPHER_ALGORITHM : algorithm;
byte[] raw = toKey(key, aesKeyType);
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] encrypted1 = new Base64().decode(data);
byte[] original = cipher.doFinal(encrypted1);
return original;
}
/**
* 转换密钥
*
* @param key
* @param aesKeyType
* @return
* @throws Exception
*/
private static byte[] toKey(String key, AESKeyType aesKeyType) throws Exception {
if (aesKeyType == AESKeyType.plain) {
return key.getBytes(CHARSET);
} else if (aesKeyType == AESKeyType.base64) {
return new BASE64Decoder().decodeBuffer(key);
}
return null;
}
}
package cn.quantgroup.cashloanflowboss.utils;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.gson.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Optional;
/**
* JSON定制化转换工具
*
* @author dengcong
*/
@Slf4j
public class JsonUtil {
public static final Gson GSON = new Gson();
/**
* 处理转换数组带来的多余小数点问题
*
* @author dengcong
*/
public static final Gson gsonDoubleAdapter = new GsonBuilder().registerTypeAdapter(Double.class,
new JsonSerializer<Double>() {
@Override
public JsonElement serialize(Double d, Type type, JsonSerializationContext context) {
DecimalFormat format = new DecimalFormat("##0"); // 不要小数点
String temp = format.format(d);
JsonPrimitive pri = new JsonPrimitive(temp);
return pri;
}
}
).create();
/**
* 转换List数组
*
* @param json
* @param cls
* @return
* @author dengcong
*/
public static <T> ArrayList<T> fromJsonList(String json, Class<T> cls) {
ArrayList<T> mList = new ArrayList<T>();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (final JsonElement elem : array) {
mList.add(GSON.fromJson(elem, cls));
}
return mList;
}
/**
* 转换List数组
*
* @param json
* @param typeToken Type type = new TypeToken<JsonResultGenericData<List<XyqbLoanApplicationHistory>>>() {}.getType();
* @return
*/
public static <T> Optional<T> fromGsonByParamType(String json, Type typeToken) {
try {
return Optional.ofNullable(GSON.fromJson(json, typeToken));
} catch (Exception e) {
log.error("[exception][fromJson_exception]json={}", json, e);
}
return Optional.empty();
}
/**
* 转换List数组
*
* @param gson
* @param json
* @param cls
* @return
* @author suntao
*/
public static <T> ArrayList<T> fromJsonList(Gson gson, String json, Class<T> cls) {
ArrayList<T> mList = new ArrayList();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (final JsonElement elem : array) {
mList.add(gson.fromJson(elem, cls));
}
return mList;
}
/**
* 避免html转义
*/
public static final Gson disableHtmlEscapeGson = new GsonBuilder().disableHtmlEscaping().create();
/**
* 转换json为对象
*
* @param jsonStr
* @param clazz
* @param <T>
* @return
*/
public static <T> Optional<T> fromJson(String jsonStr, Class<T> clazz) {
try {
return Optional.ofNullable(GSON.fromJson(jsonStr, clazz));
} catch (Exception e) {
log.error("[exception][fromJson_exception]jsonStr={}", jsonStr, e);
}
return Optional.empty();
}
/**
* jackson工具
* 转换json为对象
*
* @param jsonStr
* @param clazz
* @param <T>
* @return
*/
public static <T> Optional<T> fromJsonWithOrdinalEnum(String jsonStr, Class<T> clazz) {
try {
return Optional.ofNullable(getObjectMapper().readValue(jsonStr, clazz));
} catch (Exception e) {
log.error("[exception][fromJson_exception]error={}", e);
}
return Optional.empty();
}
/**
* jackson工具
* 转换json为对象
*
* @param jsonStr
* @param typeReference TypeReference<JsonResultGenericData<XyqbLoanApplicationHistory>> typeReference = new TypeReference<JsonResultGenericData<XyqbLoanApplicationHistory>>() {};
* @param <T>
* @return
*/
public static <T> Optional<T> fromJsonWithOrdinalEnum(String jsonStr, TypeReference typeReference) {
try {
return Optional.ofNullable(getObjectMapper().readValue(jsonStr, typeReference));
} catch (Exception e) {
log.error("[exception][fromJson_exception]jsonStr={}", jsonStr, e);
}
return Optional.empty();
}
private static ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, true);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.DATE_FORMAT_1));
return objectMapper;
}
/**
* 将对象转成json字符串
*
* @param object
* @return
*/
public static String toJson(Object object) {
return GSON.toJson(object);
}
public static String toJSONString(Object obj) {
return JSONObject.toJSONString(obj);
}
public static Object toSubString(Object addInfo, int beginIndex, int endIndex) {
return StringUtils.substring(toJSONString(addInfo), beginIndex, endIndex);
}
}
package cn.quantgroup.cashloanflowboss.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Created by tums on 2015/11/30.
*/
public final class Md5Util {
private static final Logger LOGGER = LoggerFactory.getLogger(Md5Util.class);
public static String build(String content) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest
.getInstance("md5");
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.getMessage(), e);
return null;
}
messageDigest.update(content.getBytes());
byte[] domain = messageDigest.digest();
StringBuilder md5StrBuff = new StringBuilder();
// converting domain to String
for (int i = 0; i < domain.length; i++) {
if (Integer.toHexString(0xFF & domain[i]).length() == 1) {
md5StrBuff.append("0").append(
Integer.toHexString(0xFF & domain[i]));
} else {
md5StrBuff.append(Integer.toHexString(0xFF & domain[i]));
}
}
return md5StrBuff.toString();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment