记录这个三个加密的不同,是因为在项目过程中遇到了双倍长des加密需求后,网络上到处找,没有找到准确的解释。
后续解决了这个问题,记录并分享:
1、 DES加密:也就是单倍长的DES加密、解密。
这个在网上可以找到许多类似的方法,这里就贴出一个其中一个,作为参考:
/**
* 加密方法
*
* @param src
* 源数据的字节数组
* @return
*/
public static byte[] encryptMode(String key,byte[] src) {
try {
// 生成密钥
SecretKey deskey = new SecretKeySpec(
build3DesKey(key), Algorithm);
// 实例化Cipher
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, deskey);
return cipher.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
/**
* 解密函数
*
* @param src
* 密文的字节数组
* @return
*/
public static byte[] decryptMode(String key,byte[] src) {
try {
SecretKey deskey = new SecretKeySpec(
build3DesKey(key), Algorithm);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, deskey);
return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
其中,Algorithm是String形式的"DES"。
以上,如果没有问题,那么“DES”的加解密就OK了。但在android上使用的时候,有可能出现NoSuchPaddingException这样的提示,这样的话,你可以改写以上函数的一个参数,如下:
/**
* @param encryptString
* 需要加密的明文
* @param encryptKey
* 秘钥
* @return 加密后的密文
* @throws Exception
*/
public static byte[] encryptDES(byte[] encryptString, byte[] encryptKey)
throws Exception {
// 实例化IvParameterSpec对象,使用指定的初始化向量
// 实例化SecretKeySpec类,根据字节数组来构造SecretKey
SecretKeySpec key = new SecretKeySpec(encryptKey, "DES/ECB/NoPadding");
// 创建密码器
Cipher cipher = Cipher.getInstance( "DES/ECB/NoPadding");
// 用秘钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, key);
// 执行加密操作
byte[] encryptedData = cipher.doFinal(encryptString);
return encryptedData;//Base64.encodeToString(encryptedData, Base64.DEFAULT);
}
/****
*
* @param decrypString
* 密文
* @param decryptKey
* 解密密钥
* @return
* @throws Exception
*/
public static byte[] decryptDES(byte[] decrypString, byte[] decryptKey)
throws Exception {
byte[] byteMi = decrypString;//Base64.decode(decrypString, Base64.DEFAULT);
// 实例化IvParameterSpec对象,使用指定的初始化向量
// 实例化SecretKeySpec类,根据字节数组来构造SecretKey
SecretKeySpec key = new SecretKeySpec(decryptKey, "DES/ECB/NoPadding");
// 创建密码器
Cipher cipher = Cipher.getInstance( "DES/ECB/NoPadding");
// 用秘钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, key);
// 执行解密操作
byte[] decryptedData = cipher.doFinal(byteMi);
return decryptedData;//new String(decryptedData);
}
2、3DES加密:这个就是三倍长的DES加密,其实与"DES"加密的写法没有太大的区别,将Algorithm写为"DESede"即可。
可能你在做这个加解密的时候,会遇到字节不对提示,那么可以用下面的函数来构造需要的字节数:
/**
* 根据字符串生成密钥24位的字节数组
*
* @param keyStr
* @return
* @throws UnsupportedEncodingException
*/
public static byte[] build3DesKey(String keyStr)
throws UnsupportedEncodingException {
byte[] key = new byte[24];
byte[] temp = keyStr.getBytes("UTF-8");
if (key.length > temp.length) {
System.arraycopy(temp, 0, key, 0, temp.length);
} else {
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
3、双倍长DES加密:这种情况与前两种DES主流加密有较大的不同,在网络上也没有什么特别的介绍。
双倍长DES加密中,密钥有32个字节。
步骤如下:
1、使用密钥的前16字节,对数据DATA进行加密,得到加密的结果TMP1;
2、使用密钥的后16字节,对第一的计算结果TMP1,进行解密,得到解密的结果TMP2;
3、再次使用密钥的前16字节,对第二次的计算结果TMP2,进行加密,得到加密的结果DEST。DEST就为最终的结果。
示例如下:
/**
* 双倍长des加密
* @param keyString 密钥
* @param src 数据
* @return 加密后数据
* @throws Exception
*/
public String doubleDesString(String keyString,String src) throws Exception
{
//使用密钥的前16字节,对数据DATA进行加密,得到加密的结果TMP1;
byte[] temp1=encryptDES(src.getBytes(), hexStringToBytes(keyString.substring(0, 16)));
//使用密钥的后16字节,对第一的计算结果TMP1,进行解密,得到解密的结果TMP2
byte[] temp2=decryptDES(temp1, hexStringToBytes(keyString.substring(16,32)));
//再次使用密钥的前16字节,对第二次的计算结果TMP2,进行加密,得到加密的结果DEST。DEST就为最终的结果
byte[] dest=encryptDES(temp2, hexStringToBytes(keyString.substring(0, 16)));
return bytesToHexString(dest).toUpperCase();
}
其中,bytesToHexString是转型所用函数:
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
综上,是DES加密的一些简述。供有需要的同学参考。