在之前的文章中曾讲到过DES加密算法,类似这种加密算法都有一个密钥,密钥的长度决定了加密的安全性,但是这种密钥比较难记忆,是需要存储的。PBE算法是一种基于口令的加密算法,它并不是构建了一种新的加解密算法,而是对比如DES这样的算法进行了包装,采用随机数加口令的方式保证数据的安全。在PBE算法中有口令一说,相当于我们记忆的密码,但是口令的长度以及安全性是有限的,所以这时需要采用随机数附加在口令上通过消息摘要算法经过迭代产生密钥。使破译的难度加大。常用的PBE算法有PBEWITHMD5andDES。
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import junit.framework.TestCase; public class PBETest extends TestCase { /** 算法 */ public static final String ALGORITHM = "PBEWITHMD5andDES"; /** 迭代次数 */ public static int ITERAT_COUNT = 100; /** * 构造一个8位的盐 * @return */ private byte[] initSalt() { SecureRandom random = new SecureRandom(); return random.generateSeed(8); } /** * 生成口令的Key * @param password * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private Key getKey(String password) throws NoSuchAlgorithmException, InvalidKeySpecException { PBEKeySpec spec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM); return factory.generateSecret(spec); } /** * 加密 * @param password * @param salt * @param data * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws InvalidAlgorithmParameterException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] encript(String password, byte[] salt, byte[] data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException { Key key = this.getKey(password); //实例化PBE参数材料 PBEParameterSpec params = new PBEParameterSpec(salt, ITERAT_COUNT); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, key, params); return cipher.doFinal(data); } /** * 解密 * @param password * @param salt * @param data * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws InvalidAlgorithmParameterException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] decript(String password, byte[] salt, byte[] data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException { Key key = this.getKey(password); //实例化PBE参数材料 PBEParameterSpec params = new PBEParameterSpec(salt, ITERAT_COUNT); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key, params); return cipher.doFinal(data); } public void test() throws Exception{ String data = "需要处理的数据"; String password = "123456"; byte[] salt = this.initSalt(); byte[] cryptograph = this.encript(password, salt, data.getBytes("GBK")); byte[] newData = this.decript(password, salt, cryptograph); System.out.println(data); System.out.println(Arrays.toString(cryptograph)); System.out.println(new String(newData, "GBK")); } }