在安卓不同版本或php,js等各平台DES加解密默认值设置不同,导致其结果也不同
如果想要全平台兼容,尽量自定义,少用默认设置。
以安卓为例
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, IV);
其中DES/CBC/PKCS5Padding
分别为 加密算法/加密模式/填充模式
加密算法:DES、3DES、RC4、AES
加密模式:ECB、CBC、CFB、OFB
DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种模式
填充模式:NoPadding、PKCS1Padding、PKCS5Padding、PKCS7Padding
各组合为
DES/CBC/PKCS5Padding,
DES/CFB/PKCS5Padding,
DES/ECB/PKCS5Padding,
DES/OFB/PKCS5Padding,
DES/CFB/NoPadding,
DES/CBC/NoPadding,
DES/ECB/NoPadding,
DES/OFB/NoPadding,
DES/CFB/PKCS1Padding,
DES/CBC/PKCS1Padding,
DES/ECB/PKCS1Padding,
DES/OFB/PKCS1Padding,
DES/CFB/PKCS7Padding,
DES/CBC/PKCS7Padding,
DES/ECB/PKCS7Padding,
DES/OFB/PKCS7Padding,
定义这些模式是很重要的第一步
第二点,避免使用SecureRandom生产随机IV,因为各平台版本默认算法并不兼容
尽量使用固定或自制算法生成的IV
比如最简单的
let IV = new IvParameterSpec(new java.lang.String("12345678").getBytes());
好吧给个简单的完整示例代码
public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding";
private static byte[] IV="12345678".getBytes();
/**
* DES算法,加密
*
* @param data
* 待加密字符串
* @param key
* 加密私钥,长度不能够小于8位
* @return 加密后的字节数组,一般结合Base64编码使用
* @throws Exception
*/
public static String desEncryptStr2(String data,String key) {
if (data == null)
return null;
try {
DESKeySpec dks = new DESKeySpec(key.substring(0,8).getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
IvParameterSpec iv = new IvParameterSpec(IV);
AlgorithmParameterSpec paramSpec = iv;
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
byte[] bytes = cipher.doFinal(data.getBytes());
//byte[] str=Base64.encode(bytes,0, bytes.length, 0);
//byte[] str=Base64.encode(bytes,Base64.NO_WRAP);
String str=Base64.getEncoder().encodeToString(bytes);
//return new String(str,"UTF-8");
return str;
} catch (Exception e) {
e.printStackTrace();
return data;
}
}
/**
* DES算法,解密
*
* @param data
* 待解密字符串
* @param key
* 解密私钥,长度不能够小于8位
* @return 解密后的字节数组
* @throws Exception
* 异常
*/
public static String desDecryptStr2(String data,String key) {
if (data == null)
return null;
try {
DESKeySpec dks = new DESKeySpec(key.substring(0,8).getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
IvParameterSpec iv = new IvParameterSpec(IV);
AlgorithmParameterSpec paramSpec = iv;
cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
//return new String(cipher.doFinal(Base64.decode(data,Base64.NO_WRAP)));
return new String(cipher.doFinal(Base64.getDecoder().decode(data)));
} catch (Exception e) {
e.printStackTrace();
return data;
}
}
别忘了,android最喜欢挖坑,让你痛不欲生。