des加密解密各平台兼容处理

在安卓不同版本或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最喜欢挖坑,让你痛不欲生。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注