用途:
App和后端通信时,可对参数加密,防止请求伪造或被劫持后拿到一些敏感数据。
App提交加密后的参数值,同时带上kid;服务端通过kid,拿到对应的秘钥,通过AES算法解密参数值。
当然了,不同的kid可以对应不同的秘钥和加密算法。
注意:秘钥字符串为16进制数字的字符串标识,字符范围0-9 a-f
package xx.demo.decrypt; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class Main { //这里测试发现,加密时必须使用PKCS5Padding填充模式, 解密时,则PKCS5Padding和NoPadding 都可以 //至于原理,待研究 static String[] conf = new String[] {"1.0.0", "ab3d2e93fc3ff8bd2d48e3fa39750be7", "AES", "AES/ECB/PKCS5Padding", "AES/ECB/PKCS5Padding"}; static String _source ="{this is json}"; static String _kid = "1.0.0"; public static void main(String[] args) throws Exception { //加密过程: 与解密过程相反 String encrypt = encrypt(_source, _kid); System.out.println(encrypt); //解密过程: 加密字符串->Base64解码字节数组->Crypt解密取得字节数组->utf8编码取得字符串 String src = decrypt(encrypt, _kid); System.out.println(src); } /** * 加密 * @param source 原文 * @param kid 秘钥对应的key * @return * @throws Exception */ public static String encrypt(String source,String kid) throws Exception { byte[] bytes = source.getBytes("UTF-8"); SecretKey keytmp = new SecretKeySpec(hexString2Byte(conf[1]), conf[2]); Cipher cp_en = Cipher.getInstance(conf[3]); //加密 cp_en.init(Cipher.ENCRYPT_MODE, keytmp); byte[] encrypt = cp_en.doFinal(bytes); byte[] base64Encrypt = Base64.encodeBase64(encrypt); String edata = new String(base64Encrypt, "UTF-8"); return edata; } /** * 解密 * @param data 密文 * @param kid 秘钥对应的key * @return * @throws Exception */ public static String decrypt(String data, String kid) throws Exception { byte[] original_bytes = Base64.decodeBase64(data); SecretKey keytmp = new SecretKeySpec(hexString2Byte(conf[1]), conf[2]); Cipher cp_de = Cipher.getInstance(conf[4]); //解密 cp_de.init(Cipher.DECRYPT_MODE, keytmp); byte[] zipped = cp_de.doFinal(original_bytes); String content = new String(zipped, "UTF-8"); return content; } /** * 16进制字符串转为byte[] * 举例 0xf23a -> byte[]{0xf2,0x3a} 0xf2 = -14, 0x3a = 58 * @param str (字符范围:0-9 a-f) * @return */ public static byte[] hexString2Byte(String hexStr) { String str = hexStr.toLowerCase(); for (int i = 0; i < result.length; i++) { byte b = (byte) ((((getStrIndex(str.charAt(2 * i))) & 0x0f) << 4) | ((getStrIndex(str.charAt(2 * i + 1))) & 0x0f)); result[i] = b; } return result; } public static int getStrIndex(char c) { return "0123456789abcdef".indexOf(c); } }