最近公司项目里面要对接口进行加密,服务端选用了DES来加密,作为小Android,只有去学习一些DES的基本用法,这不看不知道,有好几个大坑。
坑一:我们公司所用的框架是OKHTTP+retrofit+Rxjava,那么问题来了,我最开始是在okhttp返回的数据的时候来解密,但是获取到的死活为空
(服务端肯定没问题,因为IOS都解密成功了),然后各种百度,各种问人,后来我们公司一个Android的大神告诉我,okhttp好像是封装了解析器,在拿到数据得时候就解析过一次了,这就尴尬了,好吧,这个没办法了,只有自己重新写数据请求从服务端获取数据了(这个办法只适合少数接口,如果全部解密的话,个人建议写一个拦截器,再自己写一个数据解析器,我们公司只有几个接口,就没那个必要了)。
坑二:用了nohttp来把数据拿到了,拿到数据的时候,好高兴哦,一串很长的乱码,但是解密的时候出了问题,拿到的数据在网上DES在线解析能解
开,没毛病,但是拿到解密的代码里面,握了个草,解不开了,然后各种
试,最开始我以为是代码里面数据长度超过限制了,然后又是各种百度,
各种问人,然后那天加班搞,反正服务端不承认有问题(毕竟大牛嘛),
最后数据一遍一遍的取,一遍一遍的解析,对照,后来发现了一个很大的问题,
***DES在加密解密的时候会约定好,采用什么加密模式,采用什么填充,
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance(“DES/ECB/NoPadding”);
*原来是后台加密后,没给我说是什么填充。所以肯定解不开了,又是一个大坑。
还有一点,就是百度到的很多加密解密会用到一个Base64的类,而且还会手动给你写一个Base64类,这完全没必要的,因为Android自带了一个Base64类,直接用就行:android.util.Base64,代码如下:
byte[] byteMi = android.util.Base64.decode(data,0);
最后贴下代码哈,百度很多的:
这是加密的,传入你要加密的字符串,第二个参数是设置密码,调用这个方法会返回一个加密后的一串奇奇怪怪的东西
public static String encryptDES(String encryptString, String encryptKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
return Base64.encode(encryptedData);
}
这是解密的,传入你要解密的那一串奇怪的东西,输入密码,就会返回正常的字符串:
public static String decryptDES(String decryptString, String decryptKey) throws Exception {
byte[] byteMi = android.util.Base64.decode(decryptString,0);
SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte decryptedData[] = cipher.doFinal(byteMi);
return new String(decryptedData);
}
其实如果密码固定的话,还可以这样写,只需要调用的时候传入数据源就行了,一样的效果
private static final String DES_KEY="密码";
public static String decrypt(String data) throws Exception {
byte[] byteMi = android.util.Base64.decode(data,0);
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 从原始密匙数据创建一个DESKeySpec对象
DESKeySpec dks = new DESKeySpec(DES_KEY.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
// 一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey);
// 现在,获取数据并解密
// 正式执行解密操作
return new String(cipher.doFinal(byteMi));
}
方法调用的时候就简单了撒:
String d=DES.decrypt(response.get().toString());
直接简单粗暴,返回的string 就想怎么玩就怎么玩咯。