有时候我们做项目需要用到HTTP传参,但是带着的参数在比较敏感的情况下我们是希望密文传输的。下面是代码展示:
客户端代码(核心部分):
//需要加密传递的参数
String param = "usercode=" + userName + "&password=" + passWord;
//对param进行加密处理
String spParams = null;
try {//加密,“bbbbb”是参数在服务端解密的密钥spParams = ThreeDES.crypt(param, "bbbbb",1);}catch(Exception e){e.printStackTrace();
}
//进行url转码,避免服务端无法解密。因为参数加密之后会产生一些特殊字符,
//如果不进行url转码的话,在服务端进行解密很可能失败。
String sp = java.net.URLEncoder.encode(spParams, "UTF8");
ThreeDES类代码:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;public class ThreeDES {public static String crypt(String content,String password,int i){try {KeyGenerator generator = KeyGenerator.getInstance("AES");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(password.getBytes());generator.init(random);// generator.init(new SecureRandom(password.getBytes()));Key key = generator.generateKey();generator = null;if(i == 1){return getEncString(content,key);}else if(i == 2){return getDesString(content,key);}} catch (Exception e) {return null;}return null;}/*** 加密String明文输入,String密文输出** @param strMing* @return*/private static String getEncString(String strMing,Key key) {byte[] byteMi = null;byte[] byteMing = null;String strMi = "";BASE64Encoder base64en = new BASE64Encoder();try {byteMing = strMing.getBytes("UTF8");byteMi = getEncCode(byteMing,key);strMi = base64en.encode(byteMi);} catch (Exception e) {e.printStackTrace();} finally {base64en = null;byteMing = null;byteMi = null;}return strMi;}/*** 解密 以String密文输入,String明文输出** @param strMi* @return*/private static String getDesString(String strMi, Key key) {BASE64Decoder base64De = new BASE64Decoder();byte[] byteMing = null;byte[] byteMi = null;String strMing = "";try {byteMi = base64De.decodeBuffer(strMi);byteMing = getDesCode(byteMi,key);strMing = new String(byteMing, "UTF8");} catch (Exception e) {e.printStackTrace();} finally {base64De = null;byteMing = null;byteMi = null;}return strMing;}/*** 加密以byte[]明文输入,byte[]密文输出** @param byteS* @return*/private static byte[] getEncCode(byte[] byteS,Key key) {byte[] byteFina = null;Cipher cipher;try {cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, key);byteFina = cipher.doFinal(byteS);} catch (Exception e) {e.printStackTrace();} finally {cipher = null;}return byteFina;}/*** 解密以byte[]密文输入,以byte[]明文输出** @param byteD* @return*/private static byte[] getDesCode(byte[] byteD,Key key) {Cipher cipher;byte[] byteFina = null;try {cipher = Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE, key);byteFina = cipher.doFinal(byteD);} catch (Exception e) {e.printStackTrace();} finally {cipher = null;}return byteFina;}public static void main(String[] args) {// System.out.println(ThreeDES.crypt("bindMobile=13023130171&fenjihao=107", "bbbbb", 1));System.out.println(ThreeDES.crypt("e8fxu2q12DlkgwZHsi9OIZllSF05pGp5svbSEwAh4Gto/tleBleSuKq66Zu5QvVsoteasn0qXvIm\n" +"574UEeXpMmHXO51gzq3ut4LvV4YfYeNZJ07Yh+LYhi39J/FB15Cs8W1iru4V/0MlZqpOsMwuoQg3\n" +"kSkg0BF486q5BMkcsD0=", "bbbbb", 2));}
}
服务端接收参数进行解密(核心代码):
String sp = ServletActionContext.getRequest().getParameter("sp");
String singlePointLoginParams = ThreeDES.crypt(sp, "bbbbb",2); //解密
至此,http带参数加密传输功能结束。
注:首先需要说明的是客户端我是单独开发的一个springboot项目进行参数加密传输,服务端是一个SSH项目(比较老旧的技术)进行响应解密的。不过这都不重要,重要的是实现了,亲测可行(不管是在windows还是linux上面)。在弄这个的过程中我是有踩过坑的,这个坑就是在windows上面没问题,但是部署在linux上面就不行了,原因在于下面这段代码(获取key的值):
KeyGenerator generator = KeyGenerator.getInstance("AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
generator.init(random);
Key key = generator.generateKey();
因为在windows上默认加密解密所获得的key是一样的,所以可以成功。但是linux上则是不一样。上面的代码则是可以让加密解密所产生的key值一样,这样就可以解决问题了。