由于工作要求,需要将现有Android4.4.4平台代码迁移到Android6.0上面去,又因公司业务需要,对数据的安全性要求比较高,因此某些交互数据需要采用3Des加密进行数据传输。
在4.4.4系统上采用
/**
* @param secretKey 16位
* 密钥
* @param plainText
* 待加密数据
* @return
*/
public static String get3DESData(byte[] secretKey, String plainText) {
Key deskey = null;
String encrypt = "";
try {
// DESedeKeySpec spec = new DESedeKeySpec(secretKey);
SecretKeySpec spec = new SecretKeySpec(secretKey, "DESede");
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");// 定义加密算法,可用des,desede,blowfish
deskey = keyfactory.generateSecret(spec);// 生成秘钥
Cipher cipher = Cipher.getInstance("DESede/CBC/NOPadding");// 算法名称/加密模式/填充方式
IvParameterSpec ips = new IvParameterSpec(iv_bytes);
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
encrypt = Base64Utils.encode(encryptData);
} catch (Exception e) {
e.printStackTrace();
}
return encrypt;
}
完全没有问题,但是在6.0的系统上就会出现加解密失败的情况,解密出的明文为乱码形式。开始一直没有头绪,用的方法是一样的,只是切换了一下Android平台就导致运算失败了,后来经过进一步的测试,发现时secreKey长度的问题,在4.4平台上,当key不为24位时,系统会自动补齐,但是在6.0上可能就不会了,因此当我将key变为24位时就可以解密成功了。
摘抄:
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
-
Cipher类为加密和解密提供密码功能,转换始终包括加密算法的名称(例如,DES),后面可能跟有一个加密模式和填充方案。Cipher.getInstance的参数格式:"加密算法/加密 模式/填充模式" 或 "算法"
-
其中的参数含义为:DES为加密算法,CBC为加密模式,PKCS5Padding为填充模式.
-
常用加密算法:DES、3DES、RC4、AES等
-
加密模式:ECB、CBC、CFB、OFB等;
- DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种模式
-
填充模式:NoPadding、PKCS1Padding、PKCS5Padding、PKCS7Padding
-
-
所以有
-
- DES/CFB/PKCS5Padding,
- DES/ECB/PKCS5Padding,
- DES/OFB/PKCS5Padding,
- DES/CFB/NoPadding,
- DES/CBC/NoPadding,
- DES/ECB/NoPadding,
- DES/OFB/NoPadding,
- ........
- 我不会告诉你我是一个一个试出来哪一个能匹配上的。。。。。。
-
- 工作模式、填充模式、初始化向量这三种因素一个都不能少。否则,如果你不指定的话,那么就要程序就要调用默认实现。问题就来了,这就与平台有关了。