DES(Data Encryption Standard)的加密与MD5不同,DES可以解密,而MD5的加密是不可逆的;用于数字签名和数据加密,对称加密-即加密秘钥和解密秘钥相同。
标准的DES密钥长度为64bit,密钥每个字符占7bit,外加1bit的奇偶校验,64/(7+1)=8;所以必须是8个字符也只能是8个字符,但 .NET 里 DESCryptoServiceProvider 这个类是微软已经封装好的了,如果密钥长度不足,会以 PKCS7Padding 方式补足位。
参考资料:
常规使用参照上述链接即可,但是不同的语言有不同的实现方式,例如最近遇到的使用zeroPadding方式,java中并没有实现对应的加密方式,因此按照其原理人工进行了处理,大概原理如下:
1:先设置不做填充,即:"DES/CBC/NoPadding"
2:如果不足8位,尾端追加填充0
相关代码如下:
public class DESUtil {
/**
* 加密/解密算法-工作模式-填充模式
*/
private static final String CIPHER_ALGORITHM = "DES/CBC/NoPadding";
/**
* 默认编码
*/
private static final String CHARSET = "utf-8";
/**
* DES加密字符串
*
* @param password 加密密码,长度不能够小于8位
* @param data 待加密字符串
* @return 加密后内容
*/
public static String encrypt(String password, String data) {
if (password== null || password.length() < 8) {
throw new RuntimeException("加密失败,key不能小于8位");
}
if (data == null)
return null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
byte[] ivptext = new byte[8];
//填充
System.arraycopy(password.getBytes(CHARSET), 0, ivptext, 0,8);
IvParameterSpec iv = new IvParameterSpec(ivptext);
SecretKey secretKey=new SecretKeySpec(ivptext, "DES");//SecretKeySpec类同时实现了Key和KeySpec接口
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes(CHARSET);
int length = dataBytes.length;
//计算需填充长度
length = length + (blockSize - (length % blockSize));
byte[] plaintext = new byte[length];
//填充
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
byte[] bytes = cipher.doFinal(plaintext);
//JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder
//Android平台可以使用android.util.Base64
return new String(Base64.getEncoder().encode(bytes));
} catch (Exception e) {
e.printStackTrace();
return data;
}
}
/**
* DES解密字符串
*
* @param password 解密密码,长度不能够小于8位
* @param data 待解密字符串
* @return 解密后内容
*/
public static String decrypt(String password, String data) {
if (password== null || password.length() < 8) {
throw new RuntimeException("加密失败,key不能小于8位");
}
if (data == null)
return null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
byte[] ivptext = new byte[8];
//填充
System.arraycopy(password.getBytes(CHARSET), 0, ivptext, 0,8);
IvParameterSpec iv = new IvParameterSpec(ivptext);
SecretKey secretKey=new SecretKeySpec(ivptext, "DES");//SecretKeySpec类同时实现了Key和KeySpec接口
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET);
} catch (Exception e) {
e.printStackTrace();
return data;
}
}
}