你知道的越多,你不知道的越多
點贊再看,養成習慣
如果您有疑問或者見解,歡迎指教:
企鵝:869192208
前言
前段時間做了個與外部接口的數據對接,基於數據傳輸安全等因素的考量,需要對接口傳輸的參數進行AES加密方案,以下是對方公司提供的對接文檔的數據加密要求:
加密說明:
數據傳輸和返回的結果都用AES加密處理
AESKey:125858a550c605c199c19d778b81327b
AESIV:0392039203920300 示例:{“typeAction”:0}
加密後的字符串爲:9KdUttr+dfXTvUTSPAmxVA3l+5kR2+zPkc2N2PJiic8=
在線AES加解密測試地址:http://tool.chacuo.net/cryptaes
以上所有入參都進過加密處理 示例:
{“jsonParam”:“Mxqe9kbyWyvR64n/kiEQK7M1kGMqCZ3KgFg8Z5EVI/XajilAz16Ed7sK156EShTqwOrmZb7QdOWF/kbj2KJa/jmO+ylIe+9vdrqRRFxddY4=”}
返回參數示例:
{“errcode”:0,“data”:“lKGC/SI9dsTWZ6vc8Wtvvm0w9NZxR3XyhnlVeWq+cQkK+yce7uWr61KvZ5Eomgue44omSx2fhHef\r\nqFwWrpnM9+YLLPn5z/ODbDkshZg6/yMlTtC1PnvfNPfqN/tDscBE\r\n”,“errmsg”:""}
因爲某些國家的進口管制限制,Java發佈的運行環境包中的加解密有一定的限制。比如默認不允許256位密鑰的AES加解密,解決方法就是修改策略文件。
替換的文件:%JDK_HOME%\jre\lib\security\local_policy.jar
官方網站提供了JCE無限制權限策略文件的下載:
- JDK6的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
- JDK7的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
- JDK8的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下載後解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安裝了JRE,將兩個jar文件放到%JRE_HOME%\lib\security下覆蓋原來文件,記得先備份。
如果安裝了JDK,將兩個jar文件放到%JDK_HOME%\jre\lib\security下。
jce_policy資源合輯地址:https://download.csdn.net/download/CDWLX/12231194
下面是經過測試的完整代碼:
- 方案一
package common;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
* AES工具類
*
* <pre>
* 因爲某些國家的進口管制限制,Java發佈的運行環境包中的加解密有一定的限制。比如默認不允許256位密鑰的AES加解密,解決方法就是修改策略文件。
* 替換的文件:%JDK_HOME%\jre\lib\security\local_policy.jar
* 參考: http://czj4451.iteye.com/blog/1986483
*/
public class AESTest {
// 密鑰
public static String AESKey = "125858a550c605c199c19d778b81327b";
public static String AESIV = "0392039203920300";
private static String charset = "utf-8";
// 偏移量
private static int offset = 16;
private static String transformation = "AES/CBC/PKCS5Padding";
private static String algorithm = "AES";
/**
* 加密
*
* @param content
* @return
*/
public static String encrypt(String content) {
return encrypt(content, AESKey);
}
/**
* 解密
*
* @param content
* @return
*/
public static String decrypt(String content) {
return decrypt(content, AESKey);
}
/**
* 加密
*
* @param content
* 需要加密的內容
* @param AESKey
* 加密密碼
* @return
*/
public static String encrypt(String content, String AESKey) {
try {
SecretKeySpec skey = new SecretKeySpec(AESKey.getBytes(), algorithm);
IvParameterSpec iv = new IvParameterSpec(AESIV.getBytes(), 0, offset);
Cipher cipher = Cipher.getInstance(transformation);
byte[] byteContent = content.getBytes(charset);
cipher.init(Cipher.ENCRYPT_MODE, skey, iv);// 初始化
byte[] result = cipher.doFinal(byteContent);
return new Base64().encodeToString(result); // 加密
} catch (Exception e) {
System.out.println(e);
}
return null;
}
/**
* AES(256)解密
*
* @param content
* 待解密內容
* @param AESKey
* 解密密鑰
* @return 解密之後
* @throws Exception
*/
public static String decrypt(String content, String AESKey) {
try {
SecretKeySpec skey = new SecretKeySpec(AESKey.getBytes(), algorithm);
IvParameterSpec iv = new IvParameterSpec(AESIV.getBytes(), 0, offset);
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化
byte[] result = cipher.doFinal(new Base64().decode(content));
return new String(result); // 解密
} catch (Exception e) {
System.out.println(e);
}
return null;
}
public static void main(String[] args) throws Exception {
String s = "{\"code\":\"YWBD_GLLR\",\"params\":[{\"name\":\"ID\",\"value\":\"01265a3dc493462e9cdd4a26c41f19de\"}]}";
// 加密
System.out.println("加密前:" + s);
String encryptResultStr = encrypt(s);
System.out.println("加密後:" + encryptResultStr);
// 解密
System.out.println("解密後:" + decrypt(encryptResultStr));
}
}
運行結果:
- 方案二
Encodes.java
/**
* Copyright (c) 2005-2012 springside.org.cn
*/
package com.minstone.common.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringEscapeUtils;
/**
* 封裝各種格式的編碼解碼工具類. 1.Commons-Codec的 hex/base64 編碼 2.自制的base62 編碼
* 3.Commons-Lang的xml/html escape 4.JDK提供的URLEncoder
*
* @author calvin
* @version 2013-01-15
*/
public class Encodes {
private static final String DEFAULT_URL_ENCODING = "UTF-8";
private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
.toCharArray();
/**
* Hex編碼.
*/
public static String encodeHex(byte[] input) {
return new String(Hex.encodeHex(input));
}
/**
* Hex解碼.
*/
public static byte[] decodeHex(String input) {
try {
return Hex.decodeHex(input.toCharArray());
} catch (DecoderException e) {
throw Exceptions.unchecked(e);
}
}
public static byte[] stringToByte(String input) {
return input.getBytes();
}
/**
* Base64編碼.
*/
public static String encodeBase64(byte[] input) {
return new String(Base64.encodeBase64(input));
}
/**
* Base64編碼.
*/
public static String encodeBase64(String input) {
try {
return new String(Base64.encodeBase64(input
.getBytes(DEFAULT_URL_ENCODING)));
} catch (UnsupportedEncodingException e) {
return "";
}
}
// /**
// * Base64編碼, URL安全(將Base64中的URL非法字符'+'和'/'轉爲'-'和'_', 見RFC3548).
// */
// public static String encodeUrlSafeBase64(byte[] input) {
// return Base64.encodeBase64URLSafe(input);
// }
/**
* Base64解碼.
*/
public static byte[] decodeBase64(String input) {
return Base64.decodeBase64(input.getBytes());
}
/**
* Base64解碼.
*/
public static String decodeBase64String(String input) {
try {
return new String(Base64.decodeBase64(input.getBytes()),
DEFAULT_URL_ENCODING);
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* Base62編碼。
*/
public static String encodeBase62(byte[] input) {
char[] chars = new char[input.length];
for (int i = 0; i < input.length; i++) {
chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)];
}
return new String(chars);
}
/**
* Html 轉碼.
*/
public static String escapeHtml(String html) {
return StringEscapeUtils.escapeHtml4(html);
}
/**
* Html 解碼.
*/
public static String unescapeHtml(String htmlEscaped) {
return StringEscapeUtils.unescapeHtml4(htmlEscaped);
}
/**
* Xml 轉碼.
*/
public static String escapeXml(String xml) {
return StringEscapeUtils.escapeXml(xml);
}
/**
* Xml 解碼.
*/
public static String unescapeXml(String xmlEscaped) {
return StringEscapeUtils.unescapeXml(xmlEscaped);
}
/**
* URL 編碼, Encode默認爲UTF-8.
*/
public static String urlEncode(String part) {
try {
return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
} catch (UnsupportedEncodingException e) {
throw Exceptions.unchecked(e);
}
}
/**
* URL 解碼, Encode默認爲UTF-8.
*/
public static String urlDecode(String part) {
try {
return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
} catch (UnsupportedEncodingException e) {
throw Exceptions.unchecked(e);
}
}
}
Exceptions.java
/**
* Copyright (c) 2005-2012 springside.org.cn
*/
package com.minstone.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
/**
* 關於異常的工具類.
* @author calvin
* @version 2013-01-15
*/
public class Exceptions {
/**
* 將CheckedException轉換爲UncheckedException.
*/
public static RuntimeException unchecked(Exception e) {
if (e instanceof RuntimeException) {
return (RuntimeException) e;
} else {
return new RuntimeException(e);
}
}
/**
* 將ErrorStack轉化爲String.
*/
public static String getStackTraceAsString(Throwable e) {
if (e == null){
return "";
}
StringWriter stringWriter = new StringWriter();
e.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString();
}
/**
* 判斷異常是否由某些底層的異常引起.
*/
public static boolean isCausedBy(Exception ex, Class<? extends Exception>... causeExceptionClasses) {
Throwable cause = ex.getCause();
while (cause != null) {
for (Class<? extends Exception> causeClass : causeExceptionClasses) {
if (causeClass.isInstance(cause)) {
return true;
}
}
cause = cause.getCause();
}
return false;
}
/**
* 在request中獲取異常類
* @param request
* @return
*/
public static Throwable getThrowable(HttpServletRequest request){
Throwable ex = null;
if (request.getAttribute("exception") != null) {
ex = (Throwable) request.getAttribute("exception");
} else if (request.getAttribute("javax.servlet.error.exception") != null) {
ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
}
return ex;
}
}
Cryptos.java
package com.minstone.common.security;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.minstone.common.utils.Encodes;
import com.minstone.common.utils.Exceptions;
/**
* 支持HMAC-SHA1消息簽名 及 DES/AES對稱加密的工具類.
*
* 支持Hex與Base64兩種編碼方式.
*
* @author calvin
*/
public class Cryptos {
private static final String AES = "AES";
private static final String AES_CBC = "AES/CBC/PKCS5Padding";
private static final String HMACSHA1 = "HmacSHA1";
private static final String DEFAULT_URL_ENCODING = "UTF-8";
private static final int DEFAULT_HMACSHA1_KEYSIZE = 160; //RFC2401
private static final int DEFAULT_AES_KEYSIZE = 128;
private static final int DEFAULT_IVSIZE = 16;
private static final byte[] DEFAULT_KEY = new byte[]{-97,88,-94,9,70,-76,126,25,0,3,-20,113,108,28,69,125};
private static SecureRandom random = new SecureRandom();
//-- HMAC-SHA1 funciton --//
/**
* 使用HMAC-SHA1進行消息簽名, 返回字節數組,長度爲20字節.
*
* @param input 原始輸入字符數組
* @param key HMAC-SHA1密鑰
*/
public static byte[] hmacSha1(byte[] input, byte[] key) {
try {
SecretKey secretKey = new SecretKeySpec(key, HMACSHA1);
Mac mac = Mac.getInstance(HMACSHA1);
mac.init(secretKey);
return mac.doFinal(input);
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
/**
* 校驗HMAC-SHA1簽名是否正確.
*
* @param expected 已存在的簽名
* @param input 原始輸入字符串
* @param key 密鑰
*/
public static boolean isMacValid(byte[] expected, byte[] input, byte[] key) {
byte[] actual = hmacSha1(input, key);
return Arrays.equals(expected, actual);
}
/**
* 生成HMAC-SHA1密鑰,返回字節數組,長度爲160位(20字節).
* HMAC-SHA1算法對密鑰無特殊要求, RFC2401建議最少長度爲160位(20字節).
*/
public static byte[] generateHmacSha1Key() {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(HMACSHA1);
keyGenerator.init(DEFAULT_HMACSHA1_KEYSIZE);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
//-- AES funciton --//
/**
* 使用AES加密原始字符串.
*
* @param input 原始輸入字符數組
*/
public static String aesEncrypt(String input) {
try {
return Encodes.encodeHex(aesEncrypt(input.getBytes(DEFAULT_URL_ENCODING), DEFAULT_KEY));
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES加密原始字符串.
*
* @param input 原始輸入字符數組
* @param key 符合AES要求的密鑰
*/
public static String aesEncrypt(String input, String key) {
try {
return Encodes.encodeHex(aesEncrypt(input.getBytes(DEFAULT_URL_ENCODING), Encodes.decodeHex(key)));
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES加密原始字符串.
*
* @param input 原始輸入字符數組
* @param key 符合AES要求的密鑰
*/
public static byte[] aesEncrypt(byte[] input, byte[] key) {
return aes(input, key, Cipher.ENCRYPT_MODE);
}
/**
* 使用AES加密原始字符串.
*
* @param input 原始輸入字符數組
* @param key 符合AES要求的密鑰
* @param iv 初始向量
*/
public static byte[] aesEncrypt(byte[] input, byte[] key, byte[] iv) {
return aes(input, key, iv, Cipher.ENCRYPT_MODE);
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex編碼的加密字符串
*/
public static String aesDecrypt(String input) {
try {
return new String(aesDecrypt(Encodes.decodeHex(input), DEFAULT_KEY), DEFAULT_URL_ENCODING);
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex編碼的加密字符串
* @param key 符合AES要求的密鑰
*/
public static String aesDecrypt(String input, String key) {
try {
return new String(aesDecrypt(Encodes.decodeHex(input), Encodes.decodeHex(key)), DEFAULT_URL_ENCODING);
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex編碼的加密字符串
* @param key 符合AES要求的密鑰
*/
public static byte[] aesDecrypt(byte[] input, byte[] key) {
return aes(input, key, Cipher.DECRYPT_MODE);
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex編碼的加密字符串
* @param key 符合AES要求的密鑰
* @param iv 初始向量
*/
public static byte[] aesDecrypt(byte[] input, byte[] key, byte[] iv) {
return aes(input, key, iv, Cipher.DECRYPT_MODE);
}
/**
* 使用AES加密或解密無編碼的原始字節數組, 返回無編碼的字節數組結果.
*
* @param input 原始字節數組
* @param key 符合AES要求的密鑰
* @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
*/
private static byte[] aes(byte[] input, byte[] key, int mode) {
try {
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(mode, secretKey);
return cipher.doFinal(input);
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
/**
* 使用AES加密或解密無編碼的原始字節數組, 返回無編碼的字節數組結果.
*
* @param input 原始字節數組
* @param key 符合AES要求的密鑰
* @param iv 初始向量
* @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
*/
private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) {
try {
SecretKey secretKey = new SecretKeySpec(key, AES);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance(AES_CBC);
cipher.init(mode, secretKey, ivSpec);
return cipher.doFinal(input);
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
/**
* 生成AES密鑰,返回字節數組, 默認長度爲128位(16字節).
*/
public static String generateAesKeyString() {
return Encodes.encodeHex(generateAesKey(DEFAULT_AES_KEYSIZE));
}
/**
* 生成AES密鑰,返回字節數組, 默認長度爲128位(16字節).
*/
public static byte[] generateAesKey() {
return generateAesKey(DEFAULT_AES_KEYSIZE);
}
/**
* 生成AES密鑰,可選長度爲128,192,256位.
*/
public static byte[] generateAesKey(int keysize) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(keysize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
/**
* 生成隨機向量,默認大小爲cipher.getBlockSize(), 16字節.
*/
public static byte[] generateIV() {
byte[] bytes = new byte[DEFAULT_IVSIZE];
random.nextBytes(bytes);
return bytes;
}
}
CryptosTest.java
package common;
import org.apache.commons.codec.binary.Base64;
import com.minstone.common.security.Cryptos;
public class CryptosTest {
public static String AESKey = "125858a550c605c199c19d778b81327b";
public static String AESIV = "0392039203920300";
public static String param = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n<SPItemListDef>\n\t<TableCols name=\"YWBD_WHT_HLWWHJYDWBG\" id = \"0\">\n\t\t<List name=\"YWBD_WHT_HLWWHJYGDXX\">\n\t\t\t<TableCols id = \"0\">\n\t\t\t\t<Column>\n\t\t\t\t\t<ColName>GDQY</ColName>\n\t\t\t\t\t<ColValue><![CDATA[測試]]></ColValue>\n\t\t\t\t</Column>\n\t\t\t\t<Column>\n\t\t\t\t\t<ColName>HLWWHJYDWBG_SEQ</ColName>\n\t\t\t\t\t<ColValue><![CDATA[72ed76449b374b3bba77347561dfcc70]]></ColValue>\n\t\t\t\t</Column>\n\t\t\t\t<Column>\n\t\t\t\t\t<ColName>GDFRXM</ColName>\n\t\t\t\t\t<ColValue><![CDATA[測試]]></ColValue>\n\t\t\t\t</Column>\n\t\t\t\t<Column>\n\t\t\t\t\t<ColName>SEQ</ColName>\n\t\t\t\t\t<ColValue><![CDATA[2ec5c892b0934f6381b8d2e20dd388c7]]></ColValue>\n\t\t\t\t</Column>\n\t\t\t</TableCols>\n\t\t</List>\n\t\t<Column>\n\t\t\t<ColName>YZSDZ</ColName>\n\t\t\t<ColValue><![CDATA[廣州市]]></ColValue>\n\t\t</Column>\n\t\t<Column>\n\t\t\t<ColName>BGSQR</ColName>\n\t\t\t<ColValue><![CDATA[明動軟件]]></ColValue>\n\t\t</Column>\n\t\t<Column>\n\t\t\t<ColName>SEQ</ColName>\n\t\t\t<ColValue><![CDATA[72ed76449b374b3bba77347561dfcc70]]></ColValue>\n\t\t</Column>\n\t</TableCols>\n</SPItemListDef>";
public static void main(String[] args) {
String enCode = enCode(param);
enCode = "sU8EtK9gy/B7sOfrNrtaPf5+b6gcBA2u1i7VYVoIWd0z0S/GJBwR4NQQAaWBjqimZKysWZ3aefH3YN3xqBrG0I1O1q1zlGuDM6+P0JuZFXWOJB90wOvAFywoDBiFb6j3u4s73++BcZpTKV5HpQoWZjIA7eaVjVZX1ML5Z04xNuAnQH2ZM104v/S+5toxt8BbQgI8x1fYfU8vXiHmZkvzc/jGsg8ZDrXKa0utVMdak+EqzGFMAsj7YMclL3YFVQjW1ax0f81CU2oNWD6JMKalLmqFud1QAADhUtRkfsfsMldxLDykFV+Pzpd6OlAX34uPbWOBYdTS/unt0ExZklHE7bU/VYSAhZdZPsfxyO5usUEYMHJtv15Xqk3t8Dq9QZ28NZ1xcRK5nHoEckchLZpQyD5uXWbLdhy2GO4MS+7qSCBgV5QgUgOWN86LZgCPxmkOV5mYBxXtWI2mByOIm4d3ul8D4VBb2I04QDw/iVwOOKXuFzKL1lwuf3p9Z/ZvhTuPkLqVUQoa9f63G2flGSUIZ5oOVzQkBiJ/H/ybpRl19NTAhwZJK5QiD7OgK4DEd0WmrW64pj9Bun1yEQnSknc/zHvQw1WXQiecQ0CKF3uvUG0aOskwdZwDXvcvdXyt8+hEjGZf2CRxVjxgNRcpHl0M/S6kDhk0Yv3NXYTOspmG2SyR2Eofw8YGZxO3yWxqKzIZQOgFdFhygq/Zrtt7CUiw0+0fSRMM8wCzDKeIZr5yUdUiNUQzOdrygC2lGSPrP3GP+RcKGuHBe4N62uBrGj14IDj/74ZPjSiLm3NuOZ7pBGHVqr7RH9Uz9Sjv9coRs3At/ypVSXWpigy6Mi/ZuctnvcgK1tgAXs9QMvxVkJCzuKx0qQL7MArdFMngLySxP+1Z81It9PKXU7olc+koits5BIHWibXMF7TBBX1VDv/af+Kugjs6L+6uKBrU10XmKRrYORSaT81Ws5R5pwb9DK6psL+zjToeKH8mpTrPzPqMxV+qwYK4Yxr91xWblBxMCEdab/BljhtdOB37QrikB3ECXTSg8qWSsp1ciMnVuidP5Dmo0UUxDoKATeYhcM6r20s4v3+6TjoPTDu27lsEAUiKdS2iYCq0QUN4nZ+qehhje8uHU5KFaV9kgdAKN8MECM+GnhK+Uc1Pf02zNnetLYKu7u5bdW57JOE6ldbpu1YbUERNxX609ybDpsm9ixBreRPGy3oaWJ3Tbvtu6wVzK5ATRhfN04WnaI6Z/3H2y8OoC8tbnFdXFFbAeMPMRQIZUy/WG9dzOZ3cuCaak2OKmBWnTqABpd3yNR6ZUZOEiwd36EkGP6zWNrE0J0GlBdugU2b7";
decode(enCode);
}
private static String enCode(String param) {
byte[] aesEncrypt = Cryptos.aesEncrypt(param.getBytes(), AESKey.getBytes(), AESIV.getBytes());
System.out.println("param:" + param);
System.out.println(new Base64().encodeToString(aesEncrypt));
return Base64.encodeBase64String(aesEncrypt);
}
private static void decode(String param) {
System.out.println("param:" + param);
//System.out.println(new String(new Base64().decode(param)) );
byte[] aesDecrypt = Cryptos.aesDecrypt( new Base64().decode(param), AESKey.getBytes(), AESIV.getBytes());
System.out.println(new String(aesDecrypt));
}
}
- 運行結果
注意:在這過程中,遇到了一個坑,那就是解密的時候,最好將傳入的解密參數的 " " 替換爲 “+” ,否則報錯。
以下是實際應用的時候的部分代碼:
/**
* 描述:獲取表單業務數據xml(參數及返回值均進行AES加密)
* @author chendongwei
* @date 2020年2月18日 下午4:15:55
* @param request
* @param response
* @param info
* @param params
* @param token
*/
@RequestMapping(value = "getFormDataXMLAES", produces = "text/html;charset=UTF-8")
public void getFormDataXMLAES(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "jsonParam", required = false) String jsonParam,
@RequestParam(value = "token", required = false) String token) {
Map<String, Object> xml;
try {
//common.properties 配置了AESKey和AESIV
String AESKey = Global.getConfig("AESKey");
String AESIV = Global.getConfig("AESIV");
//對入參進行AES解密
byte[] aesDecrypt = Cryptos.aesDecrypt(new Base64().decode(jsonParam.replace(" ", "+")), AESKey.getBytes(), AESIV.getBytes());
jsonParam = new String(aesDecrypt);
//將解密後的json解析爲Map,再獲取到實際參數
Map<String, Object> maps = JSON.parseObject(jsonParam);
FormInfo info = new FormInfo();
info.setCode(maps.get("code").toString());
String params = maps.get("params").toString();
String returnDataType = maps.get("returnDataType").toString();
logger.info("code:" + maps.get("code").toString() + ",params:" + maps.get("params").toString() + ",returnDataType:" + returnDataType);
if (StringUtils.isNotBlank(token))
token = URLDecoder.decode(token, "utf-8");
boolean isGetXml = true;
if ("json".equals(returnDataType)) {
isGetXml = false;
}
xml = formInfoService.getFromDataXML(info, params, isGetXml, token, request);
...
xml.put("data", Base64.encodeBase64String(Cryptos.aesEncrypt(xml.get("rtnData").toString().getBytes("UTF-8"), AESKey.getBytes(), AESIV.getBytes())));
...
xml.put("errcode", 0);
xml.put("errmsg", null);
} catch (Exception e) {
logger.error(e.getMessage(), e);
...
}
renderString(response, xml);
}