PBE(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法。
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/**
* PBE(Password-based encryption,基于密码验证)<br>
* 其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。
*
* @author jianggujin
*
*/
public class PBECoder
{
/**
* PEB
*
* @author jianggujin
*
*/
public enum PEB
{
PBEWithMD5AndDES, PBEWithMD5AndTripleDES, PBEWithSHA1AndDESede, PBEWithSHA1AndRC2_40
}
/**
* 盐初始化
*
* @return
* @throws Exception
*/
public byte[] initSalt()
{
byte[] salt = new byte[8];
Random random = new Random();
random.nextBytes(salt);
return salt;
}
/**
* 转换密钥
*
* @param peb
* PEB算法
* @param password
* 密码
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws Exception
*/
private Key toKey(PEB peb, char[] password) throws NoSuchAlgorithmException,
InvalidKeySpecException
{
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance(peb.toString());
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return secretKey;
}
/**
* 加密
*
* @param peb
* PEB算法
* @param data
* 加密数据
* @param password
* 密码
* @param salt
* 盐
* @return
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidAlgorithmParameterException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public byte[] encrypt(PEB peb, byte[] data, char[] password, byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException
{
Key key = toKey(peb, password);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
Cipher cipher = Cipher.getInstance(peb.toString());
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
return cipher.doFinal(data);
}
/**
* 解密
*
* @param peb
* PEB算法
* @param data
* 解密数据
* @param password
* 密码
* @param salt
* 盐
* @return
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidAlgorithmParameterException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public byte[] decrypt(PEB peb, byte[] data, char[] password, byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException
{
Key key = toKey(peb, password);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
Cipher cipher = Cipher.getInstance(peb.toString());
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
return cipher.doFinal(data);
}
}