项目当中需要用到加密和解密的功能,并且加密和解密在多处会使用到,所以就写了个加密解密工具类,算是复习一下加密方面的东西。/** DES算法名称。*/
public static final String DES_NAME = "DES";
/** 默认的DES Transformation(DES/ECB/PKCS5Padding)。*/
public static final String DES_TRANSFORMATION = "DES/ECB/PKCS5Padding";
private static Cipher encryptCipher = null;
private static Cipher decryptCipher = null;
private DESUtils() {
}
static {
try {
encryptCipher = Cipher.getInstance(DES_TRANSFORMATION);
decryptCipher = Cipher.getInstance(DES_TRANSFORMATION);
} catch(Exception ex) {
log.error("Current system doesn't support " + DES_TRANSFORMATION + " provider.");
}
}
/**
* 根据给定的密钥种子生成字符串形式的密钥串。
* <p />
* 若给定的密钥种子{@code keySeed} 为{@code null} 或空字符串,则随机生成密钥。
*
* @param keySeed 密钥种子。
* @return 生成字符串形式的密钥串。
*/
public static String createKey(String keySeed) {
return key2hex(generateKey(keySeed));
}
/**
* 根据给定的密钥种子生密钥。
* <p />
* 若给定的密钥种子{@code keySeed} 为{@code null} 或空字符串,则随机生成密钥。
*
* @param keySeed 密钥种子。
* @return 密钥。
*/
public static Key generateKey(String keySeed) {
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance(DES_NAME);
} catch(NoSuchAlgorithmException ex) {
log.warn("System does not support the DES algorithm. message: " + ex.getMessage());
}
byte[] keyBytes = new byte[DESKeySpec.DES_KEY_LEN];
if(StringUtils.isNotBlank(keySeed)) {
byte[] bytes = DigestUtils.md5(keySeed.trim());
keyBytes = Arrays.copyOfRange(bytes, 8, 16);
return new SecretKeySpec(keyBytes, DES_NAME);
} else {
if(keyGen == null) {
SecureRandom random = new SecureRandom();
random.nextBytes(keyBytes);
return new SecretKeySpec(keyBytes, DES_NAME);
}
return keyGen.generateKey();
}
}
/**
* 将密钥转换成字符串。
*
* @param key 密钥。
* @return 密钥的字符串形式。
*/
public static String key2hex(Key key) {
if(key == null) {
return StringUtils.EMPTY;
}
return new String(Hex.encodeHex(key.getEncoded()));
}
/**
* 对给定的字符串进行加密操作,返回经过加密的新的字符串。
* <p />
* 加密过程中若发生错误,则返回{@code null}。
*
* @param plaintext 要加密的字符串。
* @param key 密钥。
* @return 给定字符串的密文。
*/
public static String encryptString(String plaintext, Key key) {
byte[] data = plaintext.getBytes();
byte[] endata = encrypt(data, key);
if(endata.length == 0) {
// 加密发生错误,返回null
return null;
}
return new String(Hex.encodeHex(endata));
}
/**
* 对给定的字符串进行加密操作,返回经过加密的新的字符串。
* <p />
* 该方法相当于调用<code>encryptString(plaintext, DESUtils.generatekey(keySeed))</code>。
*
* @param plaintext 要加密的字符串。
* @param keySeed 密钥种子。
* @return 给定字符串的密文。
*/
public static String encryptString(String plaintext, String keySeed) {
return encryptString(plaintext, generateKey(keySeed));
}
/**
* 对给定的字符串进行解密处理,返回解密的字符串。
* <p />
* 解密过程中若发生错误,则返回{@code null}。
*
* @param encrypttext 要解密的密文字符串。
* @param key 密钥。
* @return 给定的密文字符串的原文字符串。
*/
public static String decryptString(String encrypttext, Key key) {
if(StringUtils.isBlank(encrypttext)) {
return null;
}
byte[] bytes = null;
try {
bytes = Hex.decodeHex(encrypttext.toCharArray());
} catch(DecoderException ex) {
log.warn(ex);
}
byte[] data = decrypt(bytes, key);
return data.length == 0 ? null : new String(data);
}
/**
* 对给定的字符串进行解密处理,返回解密的字符串。
* <p />
* 该方法相当于调用<code>decryptString(encrypttext, DESUtils.generatekey(keySeed))</code>。
*
* @param encrypttext 要解密的密文字符串。
* @param keySeed 密钥种子。
* @return 给定的密文字符串的原文字符串。
*/
public static String decryptString(String encrypttext, String keySeed) {
return decryptString(encrypttext, generateKey(keySeed));
}
/**
* 根据指定的密钥,加密指定的数据。
* <p />
* 若加密发生错误,则返回长度为0的{@code byte} 空数组。
*
* @param data 要加密的数据。
* @param key 密钥。
* @return 加密后的数据。
*/
public static byte[] encrypt(byte[] data, Key key) {
try {
encryptCipher.init(Cipher.ENCRYPT_MODE, key, getSecureRandom());
return encryptCipher.doFinal(data);
} catch(NullPointerException ex) {
log.error("encryptCipher not initialized. - " + ex.getMessage());
} catch(InvalidKeyException ex) {
log.error("Initializes the specified key is not suitable for Cipher. - " + ex.getMessage());
} catch(IllegalBlockSizeException ex) {
log.error(ex.getMessage());
} catch(BadPaddingException ex) {
// 解密模式时抛出异常
ex.printStackTrace();
}
return new byte[0];
}
/**
* 根据指定的密钥,解密指定的数据。
* <p />
* 若解密发生错误,则返回长度为0的{@code byte} 空数组。
*
* @param endata 要解密的数据。
* @param key 密钥。
* @return 解密后的数据。
*/
public static byte[] decrypt(byte[] endata, Key key) {
try {
decryptCipher.init(Cipher.DECRYPT_MODE, key, getSecureRandom());
return decryptCipher.doFinal(endata);
} catch(NullPointerException ex) {
log.error("decryptCipher not initialized. - " + ex.getMessage());
} catch(InvalidKeyException ex) {
log.error("Initializes the specified key is not suitable for Cipher. - " + ex.getMessage());
} catch(IllegalBlockSizeException ex) {
log.error(ex.getMessage());
} catch(BadPaddingException ex) {
log.error(ex.getMessage());
}
return new byte[0];
}
/** 返回随机数生成器。*/
public static SecureRandom getSecureRandom() {
try {
return SecureRandom.getInstance(DES_NAME);
} catch(NoSuchAlgorithmException ex) {
return new SecureRandom();
}
}
/**
* 快速计算出字符串 {@code plaintext} 被加密后的字符串长度。
* <p />
* 该方法并不是调用DES加密方法后计算长度。
*
* @param plaintext 要计算的DES加密后的字符串长度的原文。
* @return 字符串 {@code plaintext} 被DES加密后的字符串长度。
*/
public static int lengthOfEncryption(String plaintext) {
if(plaintext == null) {
return 0;
}
byte[] bytes = plaintext.getBytes();
return (bytes.length / 8 + 1) * 16;
}
具体代码如下:
具体代码如下: