Java通常使用JCE(Java Cryptography Extension)实现DES算法。本文针对JCE讲述如何用Java调用相关API实现DES加解密。
DES全称Data EncryptionStandard, 一种对称加密算法,即加密和解密使用同一套密钥。
可以使用Java标准API自动生成一个密钥,也可以自己指定一个密钥。
自动生成密钥的方式如下示例。
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey secretKey = keygenerator.generateKey();
指定密钥的方式如下示例(密码为12345678)。
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
DESKeySpec dks = new DESKeySpec("12345678".getBytes());
SecretKey secretKey = skf.generateSecret(dks);
创建一个Cipher实例,并指定以下用斜杠(/)隔开的信息。
信息1:算法名。例如DES。
信息2:模式(可选)。例如ECB(Electronic Codebook mode)。
信息3:填充方案(可选)。例如PKCS5Padding(PCKS#5-style padding)。
代码示例如下。
Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
如下示例,将数据data加密成密文dst。
desCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] dst = desCipher.doFinal(data);
如下示例,将密文data解密成明文dst。
desCipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] dst = desCipher.doFinal(data);
下面是我针对DES算法封装的库DesUtil.java。
public class DesUtil {
private DesUtil() {}
public static SecretKey createSecretKey() throws Exception {
final KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
final SecretKey secretKey = keygenerator.generateKey();
return secretKey;
}
public static SecretKey createSecretKey(byte[] key) throws Exception {
final SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
final DESKeySpec dks = new DESKeySpec(key);
final SecretKey secretKey = skf.generateSecret(dks);
return secretKey;
}
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
final SecretKey secretKey = createSecretKey(key);
return encrypt(data, secretKey);
}
public static byte[] encrypt(byte[] data, SecretKey secretKey) throws Exception {
return encryptOrDecrypt(data, secretKey, Cipher.ENCRYPT_MODE);
}
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
final SecretKey secretKey = createSecretKey(key);
return decrypt(data, secretKey);
}
public static byte[] decrypt(byte[] data, SecretKey secretKey) throws Exception {
return encryptOrDecrypt(data, secretKey, Cipher.DECRYPT_MODE);
}
private static byte[] encryptOrDecrypt(byte[] data, SecretKey secretKey, int mode) throws Exception {
// Create the cipher
final Cipher desCipher = Cipher.getInstance("DES/ECB/NoPadding");
desCipher.init(mode, secretKey);
// Decrypt
final byte[] dst = desCipher.doFinal(data);
return dst;
}
}}
下面是完整的测试代码。分别使用自动生成的密钥和指定的特定密钥这两种方法先加密再解密。
final byte[] src = "8_bytes_".getBytes();
try {
final byte[] key = {(byte)0x13, (byte)0x82, (byte)0x33, (byte)0x64, (byte)0x69, (byte)0x80, (byte)0x00, (byte)0x66};
final byte[] dst = DesUtil.encrypt(src, key);
final byte[] _src = DesUtil.decrypt(dst, key);
System.out.println("encrypt and decrypt result: " + new String(_src));
} catch (Exception e) {
e.printStackTrace();
}
try {
final SecretKey key = DesUtil.createSecretKey();
final byte[] dst = DesUtil.encrypt(src, key);
final byte[] _src = DesUtil.decrypt(dst, key);
System.out.println("encrypt and decrypt result: " + new String(_src));
} catch (Exception e) {
e.printStackTrace();
}
执行结果如下,表明成功加解密了一段字符串。
encrypt and decrypt result: 8_bytes_
encrypt and decrypt result: 8_bytes_
注意:加密的原文长度必需是8的整数倍。