安全
PBE
- 在之前的文章中曾講到過DES加密算法无拗,類似這種加密算法都有一個(gè)密鑰梁只,密鑰的長(zhǎng)度決定了加密的安全性挫鸽,但是這種密鑰比較難記憶说敏,是需要存儲(chǔ)的。
- PBE算法是一種基于口令的加密算法丢郊,它并不是構(gòu)建了一種新的加解密算法盔沫,而是對(duì)比如DES這樣的算法進(jìn)行了包裝医咨,采用隨機(jī)數(shù)加口令的方式保證數(shù)據(jù)的安全。
- 在PBE算法中有口令一說架诞,相當(dāng)于我們記憶的密碼拟淮,但是口令的長(zhǎng)度以及安全性是有限的,所以這時(shí)需要采用隨機(jī)數(shù)附加在口令上通過消息摘要算法經(jīng)過迭代產(chǎn)生密鑰谴忧。
- 使破譯的難度加大很泊。常用的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";
/** 迭代次數(shù) */
public static int ITERAT_COUNT = 100;
/**
* 構(gòu)造一個(gè)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);
//實(shí)例化PBE參數(shù)材料
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);
//實(shí)例化PBE參數(shù)材料
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 = "需要處理的數(shù)據(jù)";
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"));
}
}