Java安全編程:基于口令加密(PBE)

安全 PBE

  • 在之前的文章中曾講到過DES加密算法,類似這種加密算法都有一個(gè)密鑰,密鑰的長度決定了加密的安全性,但是這種密鑰比較難記憶,是需要存儲(chǔ)的。
  • PBE算法是一種基于口令的加密算法,它并不是構(gòu)建了一種新的加解密算法,而是對(duì)比如DES這樣的算法進(jìn)行了包裝,采用隨機(jī)數(shù)加口令的方式保證數(shù)據(jù)的安全。
  • 在PBE算法中有口令一說,相當(dā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"));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文主要介紹移動(dòng)端的加解密算法的分類、其優(yōu)缺點(diǎn)特性及應(yīng)用,幫助讀者由淺入深地了解和選擇加解密算法。文中會(huì)包含算法的...
    蘋果粉閱讀 11,705評(píng)論 5 29
  • 前言 《圖解密碼技術(shù)》一書介紹了很多關(guān)于密碼的知識(shí),通讀一遍需要不少時(shí)間。為了方便學(xué)習(xí),我對(duì)書中關(guān)鍵的部分進(jìn)行了總...
    咖枯閱讀 7,581評(píng)論 1 25
  • 1 公鑰私鑰 2 公鑰加密 別人用A的公鑰加密傳輸?shù)男畔?,只有A的私鑰可以解密。保證了傳輸?shù)男畔⒌陌踩浴?2 私...
    skykira閱讀 1,026評(píng)論 0 1
  • 爆竹聲中一歲除,春風(fēng)送暖入屠蘇。千門萬戶曈曈日,總把新桃換舊符。 除夕之夜大家各相與贈(zèng)送,稱“饋歲”;長幼聚歡,祝...
    老實(shí)人學(xué)說話閱讀 266評(píng)論 0 1
  • 通過一個(gè)職業(yè)教育網(wǎng)站約了一個(gè)教魔方的老師,課時(shí)費(fèi)幾百。去之前,跟幾個(gè)朋友興奮地談起此事,他們get不到我興奮的點(diǎn),...
    我的朋友菜菜閱讀 4,500評(píng)論 32 53

友情鏈接更多精彩內(nèi)容