DES加解密
程序员文章站
2024-03-14 14:25:22
...
package cloud.jincheng.utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
/**
* DES对称加密算法<br/>
* DES现在已不被视为一种安全的加密算法,主要原因是使用的56位**过短
*
* @author jinCheng
*/
public class DesUtil {
/**
* **长度
*/
private static final int SECRET_KEY_SIZE = 56;
/**
* 算法名称
*/
private static final String ALGORITHM_NAME = "DES";
/**
* 算法名称/加密模式/填充方式<br/>
* 加密模式: ECB模式(电子密本方式,并且ECB模式不能使用IV向量),CBC模式(密文分组链接方式)<br/>
* 填充方式: PKCS5Padding(有填充),NoPadding(无填充,测试加密数据长度必须为8字节的倍数)
*/
private static final String TRANSFORMATION_ECB = "DES/ECB/PKCS5Padding";
private static final String TRANSFORMATION_CBC = "DES/CBC/PKCS5Padding";
/**
* 初始向量key的长度:8位
*/
private static final int IV_KEY_SIZE = 8;
private static final Charset UTF8 = StandardCharsets.UTF_8;
/**
* 默认**
*/
private static final String DEFAULT_KEY = "HYOK2J0=";
/**
* 加密
*
* @param plaintext 明文
* @param charsetName 字符集
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @param ivKey 向量key
* @return 密文
*/
public static String encrypt(String plaintext, String charsetName, String transformation, String key, String ivKey) {
try {
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE, charsetName, transformation, key, ivKey);
byte[] encrypted = cipher.doFinal(plaintext.getBytes(charsetName));
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
throw new RuntimeException("Encryption failed. Cause: ", e);
}
}
/**
* 加密
*
* @param plaintext 明文
* @param charsetName 字符集
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @return 密文
*/
public static String encrypt(String plaintext, String charsetName, String transformation, String key) {
return encrypt(plaintext, charsetName, transformation, key, key);
}
/**
* 加密
*
* @param plaintext 明文
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @return 密文
*/
public static String encrypt(String plaintext, String transformation, String key) {
return encrypt(plaintext, UTF8.name(), transformation, key);
}
/**
* 加密
*
* @param plaintext 明文
* @param transformation 加密模式(ECB/CBC)
* @return 密文
*/
public static String encrypt(String plaintext, String transformation) {
return encrypt(plaintext, transformation, DEFAULT_KEY);
}
/**
* 加密
*
* @param plaintext 明文
* @return 密文
*/
public static String encrypt(String plaintext) {
return encrypt(plaintext, TRANSFORMATION_CBC);
}
/**
* @param mode 加密/解密模式
* @param charsetName 字符集
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @param ivKey 向量key
* @return Cipher
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws UnsupportedEncodingException
* @throws InvalidKeyException
* @throws InvalidAlgorithmParameterException
*/
private static Cipher getCipher(int mode, String charsetName, String transformation, String key, String ivKey)
throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance(transformation);
if (TRANSFORMATION_CBC.equals(transformation)) {
cipher.init(mode, getSecretKey(key, charsetName), getIvParameterSpec(ivKey, charsetName));
} else if (TRANSFORMATION_ECB.equals(transformation)) {
cipher.init(mode, getSecretKey(key, charsetName));
}
return cipher;
}
/**
* 解密
*
* @param cipherText 密文
* @param charsetName 字符集
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @param ivKey 向量
* @return 明文
*/
public static String decrypt(String cipherText, String charsetName, String transformation, String key, String ivKey) {
try {
Cipher cipher = getCipher(Cipher.DECRYPT_MODE, charsetName, transformation, key, ivKey);
byte[] decode = Base64.getDecoder().decode(cipherText);
byte[] original = cipher.doFinal(decode);
return new String(original, charsetName);
} catch (Exception e) {
throw new RuntimeException("Decryption failed. Cause: ", e);
}
}
/**
* 解密
*
* @param cipherText 密文
* @param charsetName 字符集
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @return 明文
*/
public static String decrypt(String cipherText, String charsetName, String transformation, String key) {
return decrypt(cipherText, charsetName, transformation, key, key);
}
/**
* 解密
*
* @param cipherText 密文
* @param transformation 加密模式(ECB/CBC)
* @param key **
* @return 明文
*/
public static String decrypt(String cipherText, String transformation, String key) {
return decrypt(cipherText, UTF8.name(), transformation, key);
}
/**
* 解密
*
* @param cipherText 密文
* @param transformation 加密模式(ECB/CBC)
* @return 明文
*/
public static String decrypt(String cipherText, String transformation) {
return decrypt(cipherText, transformation, DEFAULT_KEY);
}
/**
* 解密
*
* @param cipherText 密文
* @return 明文
*/
public static String decrypt(String cipherText) {
return decrypt(cipherText, TRANSFORMATION_CBC);
}
/**
* 获取向量参数(IvParameterSpec),增加加密强度<br/>
* 若key长度不足IV_KEY_SIZE,则自动补0,超过则直接截取至IV_KEY_SIZE位
*
* @param ivKey 向量
* @param charsetName 字符集
* @return 向量参数
*/
private static IvParameterSpec getIvParameterSpec(String ivKey, String charsetName) throws UnsupportedEncodingException {
if (ivKey == null) {
ivKey = "";
}
StringBuffer stringBuffer = new StringBuffer(IV_KEY_SIZE);
stringBuffer.append(ivKey);
while (stringBuffer.length() < IV_KEY_SIZE) {
stringBuffer.append("0");
}
if (stringBuffer.length() > IV_KEY_SIZE) {
stringBuffer.setLength(IV_KEY_SIZE);
}
return new IvParameterSpec(stringBuffer.toString().getBytes(charsetName));
}
/**
* 获取安全**
*
* @param key **
* @param charsetName 字符集
* @return 安全**
*/
private static Key getSecretKey(String key, String charsetName) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM_NAME);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes(charsetName));
keyGenerator.init(SECRET_KEY_SIZE, secureRandom);
return keyGenerator.generateKey();
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
throw new RuntimeException("Failed to generate key. Cause: " + e);
}
}
public static void main(String[] args) {
String plaintext = "test455644ssaasfasdfasafd";
String encrypt = encrypt(plaintext, TRANSFORMATION_ECB);
System.out.println(encrypt);
System.out.println(decrypt(encrypt, TRANSFORMATION_ECB));
}
}