前言
在日常開發中,我們經常會用到各種加密算法,這裏來和大家一起看看對稱算法中的DES。對稱加密算法的特點是算法公開,計算量小,加密速度快,加密效率高,優勢在於加解密的高速度和長密鑰時的難破解性,但是,對稱加密算法的安全性依賴於密鑰,泄露密鑰就意味着任何人都可以對加密的密文進行破解。因此密鑰的保護對於加密信息是否安全至關重要。常見的對稱加密算法包括DES算法、3DES算法、AES算法。下面是一個DES的demo。
DES例子
import java.io.IOException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class DesEncrypt {
// DES加密密鑰key
public static String key = "12345678";
// DES加密
public static String encryptDES(String plaintext) {
try {
SecureRandom random = new SecureRandom();
// 創建一個DESKeySpec對象
DESKeySpec desKey = new DESKeySpec(key.getBytes());
// 創建一個密匙工廠
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 將DESKeySpec對象轉換成SecretKey對象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher對象實際完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher對象
cipher.init(cipher.ENCRYPT_MODE, securekey, random);
// 加密生成密文byte數組
byte[] cipherBytes = cipher.doFinal(plaintext.getBytes());
// 將密文byte數組轉化爲16進制密文
String ciphertext = byteToHex(cipherBytes);
return ciphertext;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
// DES解密
public static String decryptDES(String ciphertext) {
try {
SecureRandom random = new SecureRandom();
// 創建一個DESKeySpec對象
DESKeySpec desKey = new DESKeySpec(key.getBytes());
// 創建一個密匙工廠
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 將DESKeySpec對象轉換成SecretKey對象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher對象實際完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher對象
cipher.init(cipher.DECRYPT_MODE, securekey, random);
// 將16進制密文轉化爲密文byte數組
byte[] cipherBytes = hexToByte(ciphertext);
// 真正開始解密操作
String plaintext = new String(cipher.doFinal(cipherBytes));
return plaintext;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
// 將byte轉化爲16進制
public static String byteToHex(byte[] bs) {
if (0 == bs.length) {
return "";
} else {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bs.length; i++) {
String s = Integer.toHexString(bs[i] & 0xFF);
if (1 == s.length()) {
sb.append("0");
}
sb = sb.append(s.toUpperCase());
}
return sb.toString();
}
}
// 將16進制轉化爲byte
public static byte[] hexToByte(String ciphertext) {
byte[] cipherBytes = ciphertext.getBytes();
if ((cipherBytes.length % 2) != 0) {
throw new IllegalArgumentException("長度不爲偶數");
} else {
byte[] result = new byte[cipherBytes.length / 2];
for (int i = 0; i < cipherBytes.length; i += 2) {
String item = new String(cipherBytes, i, 2);
result[i / 2] = (byte) Integer.parseInt(item, 16);
}
return result;
}
}
public static void main(String[] args) {
// 待加密內容
String str = "愛琴孩的博客";
String ciphertext = encryptDES(str);
System.out.println("加密後:" + ciphertext);
String plaintext = decryptDES(ciphertext);
System.out.println("解密後:" + plaintext);
}
}
上面的例子中對加密後的字節數組,轉成16進制字符串。我們也可以對字節數組進行Base64編碼處理,只需要調用下列方法
//字節數組轉成base64編碼
public static String byte2Base62(byte[] bytes) {
BASE64Encoder base64Encoder=new BASE64Encoder();
return base64Encoder.encode(bytes);
}
//base64字符串轉成字節數組
public static byte[] base642byte(String base64Str) throws IOException {
BASE64Decoder base64Decoder =new BASE64Decoder();
return base64Decoder.decodeBuffer(base64Str);
}
演示效果如下
加密後:06B65B83FE389F9B1C095A61E3BD5D87C854D32FC0D83483
解密後:愛琴孩的博客
總結
DES加密算法在企業中使用需要注意,密鑰長度不能過低。而且就算長度較長,隨着計算機算力的提高,破解也只是時間問題。如果涉及的東西安全性要求較高,最好不用DES。