铁马冰河2000

导航

Java加解密-PBE对称加密算法

PBE

  PBE算法结合了消息摘要算法和对称加密算法的优点,是一种特殊的对称加密算法。Password Based Encryption,基于口令的加密。因为口令是比较好记的,就容易通过穷举、猜测的方式获得口令——针对这种情况,我们采用的方式是加盐(Salt),通过加入一些额外的内容(通常是随机字符)去扰乱。实现的方式有2种:JDK和BC。

应用场景:

  JDK和BC实现的PBEWithMD5AndDES的算法如下:

============================================================================PBE加解密工具类:

import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class SecurityPBE {
    
    public static String PBE_MODE_JDK = "jdk";
    public static String PBE_MODE_BC = "bouncyCastle";
    private PBEParameterSpec parameterSpec;
    private Key key;
    
    //单例模式
    private static SecurityPBE securityPBE;
    public static SecurityPBE getInstance(String password, String succurityMode) {
        if(securityPBE == null) {
            securityPBE = new SecurityPBE(password, succurityMode);
        }
        return securityPBE;
    }
    
    private SecurityPBE(String password, String succurityMode)  {
        try{
            //1.初始化盐
            SecureRandom secureRandom = new SecureRandom();//强加密随机数生成器
            byte[] salt= secureRandom.generateSeed(8);//产生盐必须是8位
            //2.口令与密钥
            if(StringUtils.isNotBlank(succurityMode) && StringUtils.equals(PBE_MODE_BC, succurityMode)) {
                Security.addProvider(new BouncyCastleProvider());//添加到provider
                PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
                SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES","BC");//指定provider
                key = factory.generateSecret(pbeKeySpec);
                parameterSpec = new PBEParameterSpec(salt, 50);
            }else {
                PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());//密钥转换的对象
                SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");//实例化密钥转换工厂
                key = factory.generateSecret(pbeKeySpec);//由工厂产生key
                parameterSpec = new PBEParameterSpec(salt, 100);//PBE输入参数的材料,盐,迭代100次
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public byte[] encrypt(byte[] array) {
        try{
            Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
            cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
            byte[] result = cipher.doFinal(array);
            return result;
        } catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
    
    public byte[] decrypt(byte[] array) {
        try{
            Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
            cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
            return cipher.doFinal(array);
        } catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
}

============================================================================PBE加解密工具测试类:

    @Test
    public void test_PBE() {
        String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串
        String password = "123456";
        SecurityPBE securityJdkPBE1 = SecurityPBE.getInstance(password, SecurityPBE.PBE_MODE_JDK);
        byte[] encodeJdkPBE = securityJdkPBE1.encrypt(src.getBytes());
        System.out.println("JDK PBE加密:" + Base64.encodeBase64String(encodeJdkPBE));
        SecurityPBE securityJdkPBE2 = SecurityPBE.getInstance(password, SecurityPBE.PBE_MODE_JDK);
        byte[] decodeJdkPBE = securityJdkPBE2.decrypt(encodeJdkPBE);
        System.out.println("JDK PBE解密:" + new String(decodeJdkPBE));
        
        SecurityPBE securityBcPBE = SecurityPBE.getInstance(password, SecurityDES3.DES3_MODE_BC);
        byte[] encodeBcPBE = securityBcPBE.encrypt(src.getBytes());
        System.out.println("bouncyCastle PBE加密:" + Base64.encodeBase64String(encodeBcPBE));
        byte[] decodeBcPBE = securityBcPBE.decrypt(encodeBcPBE);
        System.out.println("bouncyCastle PBE解密:" + new String(decodeBcPBE));
    }

 

posted on 2022-01-23 22:37  铁马冰河2000  阅读(836)  评论(0编辑  收藏  举报